Java에서 pass by reference와 동등한 작업을 수행하는 방법
다음 Java 코드:
public class XYZ {
public static void main(){
int toyNumber = 5;
XYZ temp = new XYZ();
temp.play(toyNumber);
System.out.println("Toy number in main " + toyNumber);
}
void play(int toyNumber){
System.out.println("Toy number in play " + toyNumber);
toyNumber++;
System.out.println("Toy number in play after increement " + toyNumber);
}
}
는 다음과 같이 출력합니다.
장난감 번호 5규정 6 이후 재생 중인 장난감 번호메인 5의 완구 번호
C++에 나는 다음과 같이 패스 할 수 있습니다는 C++에서는 통과할 수 있다.toyNumber변수로 참조에 의해 패스 사용하여섀도우잉을 방지합니다 변수(pass-by-reference)를:에 아래와 같이 동일한 변수의 복사본을 만드는 포지티브를 피하는 즉,다음과 같은 변수의복사본을 만듭니다.
void main(){
int toyNumber = 5;
play(toyNumber);
cout << "Toy number in main " << toyNumber << endl;
}
void play(int &toyNumber){
cout << "Toy number in play " << toyNumber << endl;
toyNumber++;
cout << "Toy number in play after increement " << toyNumber << endl;
}
C++ 출력은 다음과 같습니다.
장난감 번호 5규정 6 이후 재생 중인 장난감 번호메인 6번 완구 번호
질문입니다. Java가 참조가 아닌 값 단위로 전달된다는 점을 감안할 때 C++ 코드와 동일한 출력을 얻을 수 있는 Java의 동등한 코드는 무엇입니까?
몇 가지 선택지가 있습니다.가장 이치에 맞는 것은 당신이 무엇을 하려고 노력하느냐에 달려 있습니다.
선택 1: toyNumber를 클래스의 공용 멤버 변수로 설정
class MyToy {
public int toyNumber;
}
그런 다음 MyToy에 대한 참조를 메서드에 전달합니다.
void play(MyToy toy){
System.out.println("Toy number in play " + toy.toyNumber);
toy.toyNumber++;
System.out.println("Toy number in play after increement " + toy.toyNumber);
}
선택 2: pass by reference 대신 값 반환
int play(int toyNumber){
System.out.println("Toy number in play " + toyNumber);
toyNumber++;
System.out.println("Toy number in play after increement " + toyNumber);
return toyNumber
}
결국은 이 선택에서는 주로 다음과 같이 콜사이트를 약간 변경해야 합니다를 읽는다 이 선택은 callsite에 주요에서 작은 변화가 필요할 것이다.toyNumber = temp.play(toyNumber);..
선택지 3: 클래스 또는 정적 변수 만들기
두 함수가 동일한 클래스 또는 클래스 인스턴스 메서드인 경우 toyNumber를 클래스 멤버 변수로 변환할 수 있습니다.
선택 4: 유형 int의 단일 요소 어레이를 생성하여 전달합니다.
이는 해킹으로 간주되지만 인라인 클래스 호출에서 값을 반환하기 위해 사용되는 경우가 있습니다.
void play(int [] toyNumber){
System.out.println("Toy number in play " + toyNumber[0]);
toyNumber[0]++;
System.out.println("Toy number in play after increement " + toyNumber[0]);
}
Java는 참조에 의해 호출되지 않으며, 값에 의해서만 호출됩니다.
그러나 개체 유형의 모든 변수는 실제로 포인터입니다.
따라서 Mutable Object를 사용하면 원하는 동작을 볼 수 있습니다.
public class XYZ {
public static void main(String[] arg) {
StringBuilder toyNumber = new StringBuilder("5");
play(toyNumber);
System.out.println("Toy number in main " + toyNumber);
}
private static void play(StringBuilder toyNumber) {
System.out.println("Toy number in play " + toyNumber);
toyNumber.append(" + 1");
System.out.println("Toy number in play after increement " + toyNumber);
}
}
이 코드의 출력:
run:
Toy number in play 5
Toy number in play after increement 5 + 1
Toy number in main 5 + 1
BUILD SUCCESSFUL (total time: 0 seconds)
이 동작은 표준 라이브러리에서도 확인할 수 있습니다.예를 들어 Collections.sort(); Collections.shuffle(); 이러한 메서드는 새 목록을 반환하지 않고 해당 인수 개체를 변경합니다.
List<Integer> mutableList = new ArrayList<Integer>();
mutableList.add(1);
mutableList.add(2);
mutableList.add(3);
mutableList.add(4);
mutableList.add(5);
System.out.println(mutableList);
Collections.shuffle(mutableList);
System.out.println(mutableList);
Collections.sort(mutableList);
System.out.println(mutableList);
이 코드의 출력:
run:
[1, 2, 3, 4, 5]
[3, 4, 1, 5, 2]
[1, 2, 3, 4, 5]
BUILD SUCCESSFUL (total time: 0 seconds)
작성하다
class PassMeByRef { public int theValue; }
그런 다음 참조를 인스턴스로 전달합니다.인수를 통해 상태를 변환하는 방식은 특히 병렬 코드에서는 피하는 것이 좋습니다.
빠른 솔루션에서는 ATOMIC Integer 또는 내장된 메서드를 사용하여 메서드 내의 값을 변경할 수 있는 임의의 원자 변수를 사용할 수 있습니다.다음은 샘플 코드입니다.
import java.util.concurrent.atomic.AtomicInteger;
public class PrimitivePassByReferenceSample {
/**
* @param args
*/
public static void main(String[] args) {
AtomicInteger myNumber = new AtomicInteger(0);
System.out.println("MyNumber before method Call:" + myNumber.get());
PrimitivePassByReferenceSample temp = new PrimitivePassByReferenceSample() ;
temp.changeMyNumber(myNumber);
System.out.println("MyNumber After method Call:" + myNumber.get());
}
void changeMyNumber(AtomicInteger myNumber) {
myNumber.getAndSet(100);
}
}
출력:
MyNumber before method Call:0
MyNumber After method Call:100
당신은 자바에 있는 기준으로 기본 형식을 통과시킬 수 없다.개체 형식의 모든 변수이다 물론, 하지만 그들에게"참조"이라고 부르고 그들은 또한 항상 값으로 전달된다 pointers.
어디로 참조에 의해 원시적인 합격에 필요한 상황에서, 사람들은 때때로 원시적인 형식의 배열 다음 인수로 한 single-element 배열을 건네주는 매개 변수 선포하는 것이다 할 것이다.그래서고 메서드를에서 여러분은 배열의 내용을 변경할 수 있는 참조 int[1]을 통과해야만 한다.
public static void main(String[] args) {
int[] toyNumber = new int[] {5};
NewClass temp = new NewClass();
temp.play(toyNumber);
System.out.println("Toy number in main " + toyNumber[0]);
}
void play(int[] toyNumber){
System.out.println("Toy number in play " + toyNumber[0]);
toyNumber[0]++;
System.out.println("Toy number in play after increement " + toyNumber[0]);
}
"Pass-by..."이 Java그리고 C에 예약되어 있만약 당신이 참고로 주어져원시적인 래퍼 인스턴스를 변경할 작정이다 이것 외에도, 이 반사에 의해 행해진다.사례Integer.
public class WrapperTest
{
static void mute(Integer a)
{
try
{
Field fValue = a.getClass().getDeclaredField("value");
fValue.setAccessible(true);
fValue.set(a, 6);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
Integer z = 5;
mute(z);
System.out.println(z);
}
}
출력은 6당신의 C++예처럼.때문에 자바 설계 변경할 수 없는으로 원시적인 포장지를 고려하는 반사, 필요하다.그밖에도 다른 모든 클래스 래퍼로 마치, 배열 될 수 있다.int[]길이 1.
우리는 checkPassByValue에 a의 값에 반영되지 않a=5을 세웠다마찬가지로, 우리들은 우리들이 Person를 사용하여 그 사람이 어디 점들은 데이터를 업데이트할 수 있는 사람을 통과해야만 한다.SetName이 되지만 변화는 사람 그리고 그것은 새로운 Person()그 경우에 해당 업데이트는 주요 기능에 반영되지 않기 때문에 부디 지시하여야 한다.
class Person {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
public Person(String name) {
this.name = name;
}
}
public class PassByValueVsReference {
public static void main(String[] args) {
int a = 3;
Person person = new Person("Foo");
checkPassByValue(a, person);
System.out.println(a);
System.out.println(person.getName());
}
public static void checkPassByValue(int number, Person person) {
number = 5;
person.setName("Foo-updated");
person = new Person("Foo_new reference");
}
}
//C++ equivalent of checkPassByValue(int ,Person *);
언급URL : https://stackoverflow.com/questions/5614562/how-to-do-the-equivalent-of-pass-by-reference-for-primitives-in-java
'programing' 카테고리의 다른 글
| 설치 스크립트가 종료되어 오류: 'x86_64-linux-syslog-gcc' 명령이 실패했으며 종료 상태가 1입니다. (0) | 2022.10.31 |
|---|---|
| Python에서 텍스트 파일의 파일 내용을 지우려면 어떻게 해야 하나요? (0) | 2022.10.31 |
| MySQL 쿼리 실행을 중지하려면 어떻게 해야 합니까? (0) | 2022.10.23 |
| TypeScript, 사전을 통한 루프 (0) | 2022.10.23 |
| 목록에서 최대값의 모든 위치를 찾으려면 어떻게 해야 합니까? (0) | 2022.10.23 |