Java에서 배열이 값으로 전달되거나 참조로 전달됩니까? [복제]
가능한 중복 :
Java가 "통과 기준"입니까?
배열은 Java 의 기본 유형 이 아니지만 객체가 아니므 로 값이나 참조로 전달됩니까? 배열에 포함 된 항목 (예 : 참조 또는 기본 유형)에 따라 달라 집니까?
귀하의 질문은 잘못된 전제에 기초합니다.
배열은 Java에서 기본 유형이 아니지만 객체도 아닙니다 ... "
실제로 Java의 모든 배열 은 객체 1 입니다. 모든 Java 배열 유형은 java.lang.Object
상위 유형으로 사용되며 Object
API 의 모든 메소드 구현을 상속합니다 .
... 그러면 가치 나 참조로 전달됩니까? 배열에 포함 된 항목 (예 : 참조 또는 기본 유형)에 따라 달라 집니까?
짧은 대답 : 1) 가치에 의한 통과, 2) 아무런 차이가 없습니다.
더 긴 답변 :
모든 Java 객체와 마찬가지로 배열은 value ...로 전달되지만 값은 배열에 대한 참조입니다. 따라서 호출 된 메서드에서 배열의 셀에 무언가를 할당하면 호출자가 보는 것과 동일한 배열 객체에 할당됩니다.
이것은 통과 기준이 아닙니다. 실제 참조 별 변수에는 변수 의 주소를 전달하는 것이 포함됩니다 . 하여 실제 패스 별 참조 호출 방법은 국소 변수에 할당 할 수 있으며, 이는 호출자의 변수가 업데이트되게한다.
그러나 Java에서는 아닙니다. Java에서 호출 된 메소드는 배열의 컨텐츠를 업데이트하고 배열 참조의 사본을 업데이트 할 수 있지만 호출자의 배열 참조를 보유하는 호출자의 변수는 업데이트 할 수 없습니다. 따라서 ... Java가 제공하는 것은 참조로 전달되지 않습니다.
다음은 참조 별 전달과 값별의 차이점을 설명하는 링크입니다. 위 내 설명을 이해하지 못하는 경우 용어에 동의하는 경향 느끼는 경우, 또는, 당신은 해야 읽을.
- http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/cplr233.htm
- http://www.cs.fsu.edu/~myers/c++/notes/references.html
관련 SO 질문 :
역사적 배경 :
"by-by-reference"라는 문구는 원래 "reference-by-reference"이며, FORTRAN (참조 별 호출)의 의미를 전달하는 인수를 ALGOL-60 (값별 호출)의 의미를 전달하는 데 사용되었습니다. 이름으로 전화).
값별 호출에서 인수 표현식은 값으로 평가되고 해당 값은 호출 된 메소드에 복사됩니다.
참조 별 호출에서 인수 표현식은 부분적으로 호출 메소드에 전달되는 "lvalue"(즉, 변수 또는 배열 요소의 주소)로 평가됩니다. 그러면 호출 메소드는 변수 / 요소를 직접 읽고 업데이트 할 수 있습니다.
이름 별 호출에서 실제 인수 표현식은 호출 메소드 (!!)로 전달되어 여러 번 평가할 수 있습니다 (!!!). 이것은 구현하기가 복잡하고 이해하기 어려운 코드를 작성하는 데 사용될 수 있습니다. Call-by-name은 Algol-60에서만 사용되었습니다 (감사합니다!).
최신 정보
실제로 Algol-60의 이름 별 호출은 람다 식을 매개 변수로 전달하는 것과 유사합니다. 주름은 이러한 정확하지 않은 람다 표현 (구현 레벨에서 "썽크"로 불림) 이 호출 프로 시저 / 함수에서 범위 내에있는 변수의 상태를 간접적으로 수정할 수 있다는 것입니다. 그것은 그들이 이해하기 어렵게 만든 부분입니다. ( 예를 들어 Jensen 's Device 의 Wikipedia 페이지를 참조하십시오 .)
1. 연결된 Q & A ( Java의 배열 및 메모리에 저장되는 방법 )의 어떤 것도 배열이 객체가 아니라고 진술하거나 암시하지 않습니다.
Everything in Java are passed-by value.
. Array (객체가 아닌 객체)의 경우, 배열 참조는 값으로 전달됩니다. (객체 참조가 값으로 전달되는 것과 같습니다.)
배열을 다른 메소드에 전달하면 실제로 해당 배열에 대한 참조가 복사됩니다.
- 해당 참조를 통해 배열의 내용이 변경되면 원래 배열에 영향을줍니다.
- 그러나 새 배열을 가리 키도록 참조를 변경해도 원래 방법의 기존 참조는 변경되지 않습니다.
이 게시물을 참조하십시오 ..
Java가 "Pass-by-Reference"또는 "Pass-by-Value"입니까?
이 작업 예를보십시오 :-
public static void changeContent(int[] arr) {
// If we change the content of arr.
arr[0] = 10; // Will change the content of array in main()
}
public static void changeRef(int[] arr) {
// If we change the reference
arr = new int[2]; // Will not change the array in main()
arr[0] = 15;
}
public static void main(String[] args) {
int [] arr = new int[2];
arr[0] = 4;
arr[1] = 5;
changeContent(arr);
System.out.println(arr[0]); // Will print 10..
changeRef(arr);
System.out.println(arr[0]); // Will still print 10..
// Change the reference doesn't reflect change here..
}
배열은 실제로 객체이므로 참조가 전달됩니다 (참조 자체는 값으로 전달되어 혼란 스럽습니까?). 빠른 예 :
// assuming you allocated the list
public void addItem(Integer[] list, int item) {
list[1] = item;
}
You will see the changes to the list from the calling code. However you can't change the reference itself, since it's passed by value:
// assuming you allocated the list
public void changeArray(Integer[] list) {
list = null;
}
If you pass a non-null list, it won't be null by the time the method returns.
No that is wrong. Arrays are special objects in Java. So it is like passing other objects where you pass the value of the reference, but not the reference itself. Meaning, changing the reference of an array in the called routine will not be reflected in the calling routine.
Everything in Java is passed by value .
In the case of the array the reference is copied into a new reference, but remember that everything in Java is passed by value .
Take a look at this interesting article for further information ...
The definitive discussion of arrays is at http://docs.oracle.com/javase/specs/jls/se5.0/html/arrays.html#27803 . This makes clear that Java arrays are objects. The class of these objects is defined in 10.8.
Section 8.4.1 of the language spec, http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#40420 , describe how arguments are passed to methods. Since Java syntax is derived from C and C++, the behavior is similar. Primitive types are passed by value, as with C. When an object is passed, an object reference (pointer) is passed by value, mirroring the C syntax of passing a pointer by value. See 4.3.1, http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.3 ,
In practical terms, this means that modifying the contents of an array within a method is reflected in the array object in the calling scope, but reassigning a new value to the reference within the method has no effect on the reference in the calling scope, which is exactly the behavior you would expect of a pointer to a struct in C or an object in C++.
At least part of the confusion in terminology stems from the history of high level languages prior to the common use of C. In prior, popular, high level languages, directly referencing memory by address was something to be avoided to the extent possible, and it was considered the job of the language to provide a layer of abstraction. This made it necessary for the language to explicitly support a mechanism for returning values from subroutines (not necessarily functions). This mechanism is what is formally meant when referring to 'pass by reference'.
When C was introduced, it came with a stripped down notion of procedure calling, where all arguments are input-only, and the only value returned to the caller is a function result. However, the purpose of passing references could be achieved through the explicit and broad use of pointers. Since it serves the same purpose, the practice of passing a pointer as a reference to a value is often colloquially referred to a passing by reference. If the semantics of a routine call for a parameter to be passed by reference, the syntax of C requires the programmer to explicitly pass a pointer. Passing a pointer by value is the design pattern for implementing pass by reference semantics in C.
Since it can often seem like the sole purpose of raw pointers in C is to create crashing bugs, subsequent developments, especially Java, have sought to return to safer means to pass parameters. However, the dominance of C made it incumbent on the developers to mimic the familiar style of C coding. The result is references that are passed similarly to pointers, but are implemented with more protections to make them safer. An alternative would have been the rich syntax of a language like Ada, but this would have presented the appearance of an unwelcome learning curve, and lessened the likely adoption of Java.
In short, the design of parameter passing for objects, including arrays, in Java,is esentially to serve the semantic intent of pass by reference, but is imlemented with the syntax of passing a reference by value.
Kind of a trick realty... Even references are passed by value in Java, hence a change to the reference itself being scoped at the called function level. The compiler and/or JVM will often turn a value type into a reference.
'IT박스' 카테고리의 다른 글
TypeError : sequence item 0 : 예상되는 문자열, int found (0) | 2020.06.05 |
---|---|
Boolean의 null 값은 언제 사용해야합니까? (0) | 2020.06.05 |
React-Native, Android, Genymotion : ADB 서버가 ACK하지 않았습니다 (0) | 2020.06.05 |
두 이미지를 비교하는 알고리즘 (0) | 2020.06.05 |
List에서 고유 한 값 목록 가져 오기 (0) | 2020.06.05 |