2013-06-05 2 views
3

내 질문은 기본적이지만 100 % 모든 것을 이해하고 싶습니다. 너무 많은 질문이 내 게시물 referes,하지만 난 만족스러운 답변을 찾지 못했습니다.열거 형 참조 또는 프리미티브 (예) - 얕은/깊은 복사

자바의 열거 형은 참조 유형이라는 것을 알고 있습니다. 시험의 복사 생성자가 얕은 복사본을 만들기 때문에

public static class A { 
    public int i; 
    public A(int i) { 
     this.i = i; 
    } 
} 

public static class Test { 
    int i; 
    A a; 

    public Test(int i, A a){ 
     this.i = i; 
     this.a = a; 
    } 

    public Test(Test oldTest){ 
     this.i = oldTest.i; 
     this.a = oldTest.a; 
    } 
} 

public static void main(String[] args) { 
    Test t1 = new Test(10, new A(100)); 
    System.out.println(t1.i + " " + t1.a.i); 
    Test t2 = new Test(t1); 
    t2.i = 200; 
    t2.a.i = 3983; 
    System.out.println(t2.i + " " + t2.a.i); 
    System.out.println(t1.i + " " + t1.a.i); 

} 

출력은 매우 분명하다 :

10 100 
200 3983 
10 3983 

을하지만 자바의 열거는 유형을 참조하고 있기 때문에 나는 한 가지를 이해하지의는 다음 코드를 살펴 보자.

public static enum TestEnum { 
     ONE, TWO, THREE;   
    } 

    public static class Test { 
     int i; 
     TestEnum enumValue; 

    public Test(int i, TestEnum enumVar){ 
     this.i = i; 
     this.enumValue = enumVar; 
    } 

    public Test(Test oldTest){ 
     this.i = oldTest.i; 
     this.enumValue = oldTest.enumValue; // WHY IT IS OK ?? 
    } 
} 

public static void main(String[] args) { 
    Test t1 = new Test(10, TestEnum.ONE); 
    System.out.println(t1.i + " " + t1.enumValue); 
    Test t2 = new Test(t1); 
    t2.i = 200; 
    t2.enumValue = TestEnum.THREE; // why t1.emunValue != t2.enumValue ?? 
    System.out.println(t2.i + " " + t2.enumValue); 
    System.out.println(t1.i + " " + t1.enumValue); 

} 

내가 기대 한 출력 :의를 열거하여 클래스를 대체 할 수

10 ONE 
200 THREE 
10 THREE <--- I thought that reference has been copied... not value 

하지만이있어 :

10 ONE 
200 THREE 
10 ONE 

질문 : 왜? 내 생각이 틀린 곳?

답변

4

여기에는 열거 형에 특별한 것이 없습니다. 문자열을 사용하거나 유형을 사용하면 완전히 동일한 동작을 볼 수 있습니다.

두 개의 Test 개체는 완전히 별개입니다. 당신이 쓸 때 : 두 번째 객체 내에서 enumValue 필드의 값을 변경하고

t2.enumValue = TestEnum.THREE; 

것은 TestEnum.THREE가 참조하는 객체에 대한 참조가 될 수 있습니다.

enumValue 필드 (t2 통해 t1 통해 한 개)는 완전히 분리된다. 한 필드를 변경해도 다른 필드는 변경되지 않습니다.

자, 대신 당신은 당신의 열거가 변경 가능했다 (나는 강하게 낙담 것이다)와 같은 뭔가 코드를 변경 한 경우 : t1.enumValue를 통해 볼 수있을 것이라고 그리고 ...

t2.enumValue.someMutableField = "a different value"; 

왜냐하면 둘 다 동일한 객체를 참조하기 때문입니다.

그것은 Test의 인스턴스 내에서 필드를 변경하고 Test의 인스턴스를 통해 범위 일어날 객체 내에서 필드를 변경 구별 정말 중요합니다.

다시 말하지만, 실제로 이것은 열거 형에 관한 것이 아닙니다. enumValue 필드를 String 필드로 변경하고 아이디어를 얻는 것이 더 간단 할 것입니다.