2010-11-30 8 views

답변

67

Java에서 참조로 직접 프리미티브를 전달하는 방법은 없습니다.

대신 해결 방법은 래퍼 클래스의 인스턴스에 대한 참조를 전달하는 것입니다. 래퍼 클래스의 인스턴스에 대한 참조는 멤버 필드로 포함됩니다. 이러한 래퍼 클래스는 직접 작성하는 매우 간단 수 :

public class IntRef { public int value; } 

그러나 방법에 대한 래퍼 클래스를 사전 구축, 그래서 우리는 우리 자신을 작성할 필요가 없습니다?OK :

아파치 commons-lang 변경 가능한 * 클래스 :
장점 : 단일 스레드 사용을 위해 좋은 성능을 제공합니다. 완전성.
단점 : 타사 라이브러리 종속성을 도입했습니다. 내장 된 동시성 컨트롤이 없습니다.
대표 클래스 : MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.

java.util.concurrent.atomic 원자 * 클래스 :
장점 : 표준 자바 (1.5 이상) API의 일부입니다. 기본 제공 동시성 제어.
단점 : 단일 스레드 설정에서 사용하면 성능이 저하됩니다. 일부 데이터 유형에 대한 직접 지원이 누락되었습니다 (예 : AtomicShort가 없습니다.
대표 클래스 : AtomicBoolean, AtomicInteger, AtomicLongAtomicReference.
참고 : 사용자 ColinD shows in his answer처럼 AtomicReference를 사용하여 누락 된 클래스 중 일부를 대략적으로 나타낼 수 있습니다. AtomicShort.

길이 1 개 프리미티브 배열
OscarRyz's answer는 프리미티브 값을 "래핑"로, 길이 1 어레이를 사용하여 설명한다.
장점 : 빠른 쓰기. 수행자. 타사 라이브러리가 필요하지 않습니다.
단점 : 약간 더러움. 내장 된 동시성 컨트롤이 없습니다. 자체 문법을 따르지 않는 코드 결과 : 메서드 서명의 배열로 여러 값을 전달할 수 있습니까? 아니면 참조 에뮬레이션을위한 비계로서 여기에 있습니까?

또한 StackOverflow의 질문에 "Mutable boolean field in Java"에
답변을 참조하십시오.

내 의견 자바에서
, 당신은 아껴서 여부에 위의 모든 방법을 사용하기 위해 노력합니다. C에서는 함수의 반환 값을 사용하여 상태 코드 (SUCCESS/FAILURE)를 전달하는 반면 일반적으로 함수의 실제 출력은 하나 이상의 출력 매개 변수를 통해 전달됩니다. Java에서는 리턴 코드 대신 예외를 사용하는 것이 가장 좋습니다. 이렇게하면 메소드 반환 값을 실제 메소드 출력 (대부분의 Java 프로그래머가 out 매개 변수보다 자연 스럽다는 것을 알 수있는 디자인 패턴)을 전달하는 데 사용할 수 있습니다.

+0

Atomics는 여러 번 호출되는 함수에 카운터를 전달하는 것이 매우 편리합니다. 특히 카운터의 증가가 함수에서 조건 적이지만 증가시키지 않아도 반드시 실패한 것은 아닙니다. 어쨌든,이 답변을 주셔서 감사합니다. 매우 도움이됩니다. – Nyerguds

1

Java에서는 불가능합니다.

13

Java에서 아무 것도 참조로 전달되지 않습니다. 그것은 모두 가치에 의해 전달됩니다.

편집 : 프리미티브와 객체 유형 모두 값으로 전달됩니다. 전달 된 값/참조를 변경하거나 원래 값/참조가 변경 될 것을 기대할 수는 없습니다. 예 :

String a; 
int b; 

doSomething(a, b); 

... 

public void doSomething(String myA, int myB) { 
    // whatever I do to "myA" and "myB" here will never ever ever change 
    // the "a" and "b" 
} 

유일한 방법은 상관없이 원시적 또는 참조되는 이러한 장애물 이겨내 컨테이너 객체를 전달하거나, 리턴 값을 사용하는 것이다. 홀더와

:

private class MyStringHolder { 
    String a; 
    MyStringHolder(String a) { 
    this.a = a; 
    } 
} 

MyStringHolder holdA = new MyStringHolder("something"); 

public void doSomething(MyStringHolder holder) { 
    // alter holder.a here and it changes. 
} 

리턴 값

int b = 42; 
b = doSomething(b); 

public int doSomething(int b) { 
    return b + 1; 
} 
+6

에 기술적으로는 맞지만 중요하지는 않습니다. –

+0

좋습니다. –

+0

"Correct"는 부울 조건이며 학위 또는 종류의 수식어를 허용하지 않습니다. – tchrist

2

으로는 필드로 해당 값을 갖는 객체를 전달.

-2

하나의 옵션은 java.lang.Integer와 같은 클래스를 사용하는 것입니다. 그러면 원시를 전혀 전달하지 않을 것입니다. 한편

, 당신은 같은 코드를 사용할 수 있습니다

int a = 5; 
a = func(a); 

및 수정 된 값을 반환 FUNC있다.

+6

java.lang.Integer 및 friends는 변경할 수 없습니다. java.util.concurrent.atomic.AtomicInteger 및 friends는 변경 가능합니다. 필자가 보았던 다른 종류의 (총체적인) 옵션은 1 요소 배열을 사용하는 것입니다. –

+0

이것은 단일 값에 대해이를 달성하는 한 가지 방법입니다! –

3

수 없습니다. 하지만 당신은

int i = 0; 
i = doSomething(i); 

는 하나 이상의 전달되는 경우 (클래스에 전달 될 수있는 변수의 집합을 포함하기 위해 특별히 클래스)를 Data Transfer Object를 생성 할 수있는 수정 된 값을 정수를 반환 할 수 있습니다 .

13

AtomicInteger, AtomicBoolean 등을 대신 전달하십시오. 모든 기본 유형에 대해 하나도 없지만 필요한 경우 AtomicReference<Short>을 사용할 수도 있습니다.

참고 사항 : 자바에서는 이와 같은 작업을 거의 수행 할 필요가 거의 없습니다. 원할 때, 당신이하려고하는 것을 다시 생각해보고 다른 방법으로 그것을 할 수 없다면 (int을 반환하는 방법을 사용하는 것이 좋습니다. 상황은 상황에 따라 다릅니다.)

+0

+1 나는 래퍼/홀더 객체를 사용하는 것과 비교할 때 이것이 무거울 수 있다고 생각합니다. –

+0

'set (int)'을 사용하여 변형 할 경우, 걱정할 가치가있는 성능상의 영향은 없을 것이라고 생각합니다. 자신 만의 가변 래퍼를 만들거나 (커먼즈 - 랑 가져 오기) ...) 내 의견으로는 훨씬 더 나쁜 범죄가 될 것입니다. 또한 이것이 실제로 필요한 많은 경우가 있다고 생각하지 않기 때문에 이것이 자주 수행되지 않기를 바랍니다. – ColinD

+0

commons-lang을 가져 오는 것에 동의하십시오. 나는 OP가 C 프로그래머라고 생각하고 C 프로그램을 이해하는 데있어 대부분의 복잡성을 야기하는 동일한 패러다임을 계속 사용하기를 원한다. 그래서이 "pass primitive by reference"솔루션을 아주 자주 사용하게 될 것이라고 상상한다. . –

10

Java에서는 불가능합니다. 대안으로 단일 요소 배열로 래핑 할 수 있습니다.

void demo() { 
    int [] a = { 0 }; 
    increment (a) 
} 
void increment(int [] v) { 
    v[0]++; 
} 

그러나 항상 더 나은 옵션이 있습니다.

관련 문제