2011-12-23 4 views
1

이것은 StackOverflow의 첫 번째 질문입니다. 이 문제의 코드입니다 :왜이 변수가 영향을 받습니까?

public class ListStuff { 
    public static void main(String [] args) { 

    String[] randomNames = {"Herbie", "Jaco", "Pat", "Michael"};   
    String[] reversedNames = revertNames(randomNames); 

    for (int i = 0; i < reversedNames.length; i++) { 
     System.out.println(reversedNames[i]); 
    } 
    } 

    public static String[] revertNames(String[] s) { 

    for (int i = 0; i < s.length/2; i++) { 
     String tmp = s[s.length - 1 - i]; 
     s[s.length - 1 - i] = s[i]; 
     s[i] = tmp; 
    } 

    return s; 
    } 
} 

이 코드는 잘 실행하고 복귀로 reversedNames 변수 인쇄; 거기에 아무런 불만이 없습니다. 내 주요 관심사는, 그러나 내가 String[] reversedNames = revertNames(randomNames); 할 때, 변수 randomNames도 되돌릴 가져옵니다. 나는 randomNames = blabla;을 사용하여 randomNames 변수를 변경하지 않으므로 그 변수가 왜 인수로만 전달 되더라도 그 변수가 자체 버전으로 계속 변경되는지 확인하지 못합니다.

저는 약 1 년 동안 프로그래밍을 해왔고 변수 범위에 대한 지식은 매우 제한적입니다. 누구든지 올바른 방향으로 나를 가리킬 수 있습니까?

답변

3

이는 값이 아닌 참조로 배열을 전달하기 때문입니다. 기본적으로 이것은 reversedNames 배열이 여전히 randomNames 배열을 가리킴을 의미하므로 하나를 변경하면 다른 배열이 변경됩니다. 처음

: 여기서

는 변수이다

randomNames <-------- s 

s 배열 여전히 randomNames 어레이로 다시 점수 저희 revertNames 함수를 입력으로서

randomNames 

! 따라서 s을 변경하면 randomNames도 변경됩니다. randomNames

randomNames <--------- s <--------- reversedNames 

따라서, reversedNames 포인트 : 우리가 기능을 중단으로

. 함수가 호출 완료

후 : s 배열이 사라졌다

randomNames <--------- reversedNames 

있지만, reversedNames 여전히 randomNames를 가리 킵니다. 자바

public static String[] revertNames(String[] oldarray) { 
    // Create temporary array to avoid affecting original array 
    String[] s = oldarray.clone(); 
    ... 
+0

왜 downvote? – mc10

+0

와우. 가장 빠른 응답, 위대한 애호가들, 나는 이것을보고 변이를 가지고 놀 것입니다. =) – user1114051

+0

지금 투표를 변경했습니다 ... 초기 응답은이 문제에 대한 통찰력을 제공하지 못했습니다. +1 –

7

배열은 참조 유형이 있습니다

revertNames 함수 내에서 임시 변수를 만들어이 문제를 해결하려면. 즉, 배열을 revertNames 메소드로 전달하면 해당 메소드 내부의 변경 사항도 바깥에 표시됩니다. 이 코드 revertNames 내부의 배열 매개 변수 s을 변경하기 때문에 :

String tmp = s[s.length - 1 - i]; 
s[s.length - 1 - i] = s[i]; 
s[i] = tmp; 

s 대신에 전달 된 원래 배열 randomNames는 과정에서 변경됩니다.

1

revertNames 본문 내에 변수 s가 있습니다. 이것은 배열 인 객체에 대한 참조입니다. 실제의 배열은 randomNames 배열입니다. 그래서 당신은 실제로 소스 배열에서 값을 변경하고 있습니다.

배열을 사용하는 경우.copy() 당신은 독립적 인 배열을 얻을 수 있습니다 - 복사본은 원래 배열과 같은 문자열을 가리키지 만, Strings는 안전합니다.

0

당신은 사용할 수 있습니다 : StringBuffer를이 : 당신은 당신이 선언 한

String[] randomNames; 

를 선언하는 경우 자바

public class t { 
    public static void main(String [] args) { 

    String[] randomNames = {"Herbie", "Jaco", "Pat", "Michael"};   
    StringBuffer rev; 
    for (int i = 0; i < randomNames.length; i++) 
    { 
     rev=new StringBuffer(randomNames[i]); 
     System.out.println(rev.reverse().toString()); 
    } 
    } 
} 
0

배열은, 예를 참조 종류 :) (

같은 어떤 것을 반대 문자열 배열 인 객체에 대한 참조를 보유하는 지역 변수입니다.

String[] otherNames = randomNames; 

변수 otherNames에 변수 randomNames의 콘텐츠를 복사하지만, 내용은 참조입니다. 즉,이 명령문은 otherNames와 randomNames가 동일한 배열 객체를 참조하도록합니다.

String[]을 메서드 매개 변수로 전달하면 마찬가지입니다. 즉, 로컬 변수 srevertNames이고 로컬 변수 randomNamesmain에 동일한 참조가 포함됩니다. 즉 동일한 배열 객체를 참조합니다. 즉, 해당 배열 객체의 상태는 srandomNames 모두 표시됩니다.

엄밀히 말하면 변수 randomNames은 수정되지 않았으므로 (즉, 여전히 동일한 배열을 가리킴) 범위 지정과 아무 관련이 없습니다. 수정되는 것은 그것이 참조하는 대상입니다.

관련 문제