2012-08-13 3 views
2

클래스 외부에 개인 생성자가있는 클래스를 인스턴스화하는 경우이 코드를 온라인으로 발견했습니다. 어떻게 작동하는지 이해할 수 없습니다. 이전에 읽은 것에서부터 클래스의 개인 생성자를 사용하여 클래스 외부에서 인스턴스화 할 수 없습니다.클래스 외부에서 인스턴스화 된 개인 구성의 클래스

public final class A extends B { 
    private A(Something, Something) 
    { 
    //Something 
    } 

    public void someMethods() 
    { 
    //Something 
    } 
} 

public final class B { 
    private A a; 
    public void someMethod() 
    { 
    final ObjectInputStream objectInputStream = new ObjectInputStream(
          new ByteArrayInputStream(buffer.toByteArray())); 
    a = (A) objectInputStream.readObject(); 
    objectInputStream.close(); 

    a.someMethods(); 
    } 
} 

여기 정확히 무슨 일이 일어나고 있는지 알고 싶습니다. 나는 ObjectInputStream에 독서를 시도했다 그러나 그것에서 무엇이든을 얻을 수 없었다.

답변

2

개체가 생성되지 않고 비 직렬화되기 때문에 생성자는 호출되지 않습니다. 따라서 액세스 한정자는 여기에 영향을 미치지 않습니다.

기본적으로 직렬화는 힙 콘텐츠의 일부를 일부 스트림/파일 등에 기록하는 프로세스입니다. 객체를 생성하면 힙에 새로운 객체가 만들어지고 생성자가 초기화되어 초기화됩니다. 그런 다음 직렬화 중에 유지되는 상태가 있습니다. 따라서 deserialize 될 때 해당 객체를 다시 초기화 할 필요가 없습니다. 스트림/파일에서 힙 부분을 메모리로 다시 읽는 것과 같습니다.

그 외에도 리플렉션을 사용하여 액세스 한정자를 우회 할 수있는 방법이 있음을 명심하십시오.

+0

이렇게하면이 특정 객체가 정적 객체처럼 작동한다는 의미입니까? 그것이 힙 형태로 매핑되었으므로 그 중 하나의 인스턴스 만 존재할 것입니다. 내가 확실한 지 모르겠다. – noMAD

+1

글쎄, 객체가 클래스의 인스턴스이기 때문에 항상 객체의 인스턴스는 하나뿐입니다. 이것이 싱글 톤 (클래스의 한 인스턴스)과 같은 것이면, 대답은 아니오입니다. 동일한 클래스의 여러 객체를 직렬화 및 비 직렬화 할 수 있습니다. – Thomas

1

이것은 직렬화와 관련이 있으며, 비 직렬화 할 때 생성자는 실제로 호출되지 않습니다.

5

코드가 직렬화를 통해 객체를 인스턴스화 한 다음 해당 객체를 클래스 A로 캐스팅하는 것처럼 보입니다. 여기에 클래스 A 생성자가 호출됩니다.

+0

+1 deserialization을 수행하기 위해 생성자에 액세스 할 필요가 없습니다. –

+2

OpenJDK에서는 생성자를 호출하지 않고 클래스의 인스턴스를 할당하는'Unsafe.allocateInstance (Class)'를 호출합니다. 필드를 직렬화 할 때 필드를 복원하려면이 작업을 수행해야하며 생성자는 부작용이있을 수 있습니다. –

+0

참고로 OP가 더러운 해킹 일 수 있습니다. –

관련 문제