2016-07-10 2 views
0

최근 면접에 나는 재미있는 질문이 있었다.최종 클래스를 Java로 변경할 수 있습니까?

final class Example { 
    private int i; 
    private String s; 
    private Object o; 
    // get, set 
} 

그리고이 클래스 Example e = new Example();

의 예를 우리는 어떻게 든이 인스턴스는 불변 만들 수 : 우리는 변경 가능한 클래스가? 원래 클래스를 변경하지 않고.

내 생각 :이 인스턴스의

  1. 깊은 복제? 그러나 그것이 가능한지 확실하지 않습니다.
  2. 아마 serialization/deserialization과 같은 것일 수 있습니까?
+2

현재 확장 할 수 없으며 멤버 변수를 변경할 수 없습니다 (중첩 된 클래스가 아니고 변수를 변경하는 다른 코드를 표시하지 않는 경우). –

+2

물론, 매우 까다로운 관점에서 볼 때 리플렉션의 사용으로 인해 Java에서 불변성을 실제로 가질 수는 없지만, 그렇다고해서 이것이 당신이 얻을 수있는 불변과 거의 같습니다. – Gavin

+1

@Gavin 클래스는 필드에 값이 없으므로 액세스 할 수 없기 때문에 변경할 수 없습니다. –

답변

0

해당 필드의 각각의 getter/setter를 가지고 있다면, 그것은 게터이 때 당신이 private

  • final 각 필드의 복사본을 만들고 각 필드를 확인

    1. 해야합니다, 그것은 불변 수 있도록
    2. 모든 세터 제거
    3. 클래스를 변경하는 클래스 내에서 상태를 제거하거나 새 게터를 사용하여 내부에 액세스해야합니다.
  • +1

    클래스에는 상태를 변경시키는 메소드도 없어야합니다. –

    +0

    필드도 최종이어야합니다. – Gavin

    0

    Immutability는 인스턴스가 아닌 클래스의 속성입니다. 클래스를 변경하기 위해 바이트 코드 트위 들링이나 다른 수단이 필요하지 않습니다. 불가능합니다.

    최종 클래스가 없으면 불변 데코레이터를 생성합니다. 그렇게하면 인스턴스가 변경되지 않지만 해당 인스턴스에 변경할 수없는 래퍼를 제공합니다.

    당신은 불가능을 변경하고, 어떤 변수/필드에 인스턴스를 할당 할 수 있습니다, 당신의 코드에서 (당신이 그것을 서브 클래스 수 없습니다 당신이 Example 클래스 에 수정을 할 수없는 경우

    2

    ) 및 , 그것은 final으로 표시됩니다) 내가 생각할 수있는 가장 가까운 해결책은 불변 인 래퍼 클래스를 만드는 것입니다. 이것은 완벽한 해결책이 아니며 단점이 있습니다.

    첫째, 어떻게 그것을 할 :

    final class ImmutableExample { 
        // Redeclare every field as in the Example class 
        // but make sure they can't be reassigned 
        // (in this case I'll declare them as final) 
        private final int i; 
        private final String s; 
        private final Object o; 
    
        ImmutableExample(Example mutableExample) { 
         // copy fields from original 
         this.i = mutableExample.getI(); 
         this.s = mutableExample.getS(); 
         this.o = mutableExample.getO(); 
        } 
    
        // add getters but definitely no setters 
    } 
    

    을 그런 다음 같은 코드가 사방 :

    Example e = new Example(); 
    e.setI(42); // etc 
    

    변경하려면 다음

    Example e = new Example(); 
    e.setI(42); // etc 
    ImmutableExample immutableE = new ImmutableExample(e); 
    

    을 그리고 immutableE에 대한 참조를 주위에 전달 e 참조가 이탈하지 않는지 확인하십시오.단점에 대한 지금

    : 당신은 변경 가능한 유형을 예상하는 방법에 불변의 유형을 통과 할 수 있도록

    • ImmutableExampleExample의 인스턴스가 아닌, 그리고 if (immutableE instanceof Example) 또는 (Example)immutableE 같은 작업은 작동하지 않습니다 이전과 같이

    • Example의 모든 필드도 변경 불가능하거나 ImmutableExample도 변경할 수 있어야합니다. 예를 들어 Object 필드가 HashMap 또는 Date과 같이 변경 가능한 항목 일 수 있습니다.

    • Example 클래스가 변경되면 ImmutableExample에서 변경을 반복해야합니다.

    Example 하위 클래스 수 있었다 경우, 또는이 인터페이스 인 경우,이 방법이 더 유용 할 수도 있지만, Example는 서브 클래스 할 수없는 경우 나 다른 방법을 볼 수 없습니다.

    관련 문제