일부 코드에서 findbugs를 실행 중이며 serialization/unserialization을 위해 readObject (...) 메서드를 private로 호출해야한다고 말합니다. 왜? 그것이 공개되면 문제는 무엇입니까?FindBugs는 readObject (...)를 직렬화에 대해 비공개로 설정하려고합니다. 그 이유는 무엇입니까?
답변
약 readObject()/writeObject()
은 비공개입니다. 여기 거래가 있습니다. 클래스 막대가 일부 클래스 Foo를 확장하면; Foo도 readObject()/writeObject()
을 구현하고 Bar도 readObject()/writeObject()
을 구현합니다.
이제 Bar 객체가 직렬화되거나 직렬화 해제되면 JVM은 Foo와 Bar 모두에 대해 readObject()/writeObject()
을 자동으로 호출해야합니다.이러한 수퍼 클래스 메서드를 명시 적으로 호출 할 필요가 없습니다. 다만, 이러한 메소드가 private 인 경우, 메소드 오버라이드 (override)가되어, JVM는 더 이상 서브 클래스 객체의 슈퍼 클래스 메소드를 호출 할 수 없습니다.
따라서 개인적이어야합니다!
왜 findbugs가 버그라고 생각하는지 모르겠지만 두 가지 이유가있을 수 있습니다. 호출 코드가 클래스의 내부 구조를 볼 수 있기 때문에 readObject public이 캡슐화를 중단시킵니다. 또한 공개로 설정하면 모든 파생 클래스가 public으로 readObject를 선언하도록합니다. 따라서 클래스가 최종적인 것이 아니라면 직렬화 계약을 변경해야합니다.
findbugs가 대부분의 메시지에 대한 근거를 제공 할 수 있다고 생각했습니다. 이것에 대해 말할 것이 있습니까?
readObject
과 같은 직렬화 방법을 직접 호출 할 필요는 없으며 다른 클래스보다 훨씬 덜 복잡합니다. 가능한 모든 것에 대한 가시성을 최소화해야합니다.
편집 : 하위 클래스가 비헤이비어를 변경할 수있게하려면 protected
... 허용됩니다.
이 메서드를 public으로 지정하려는 유일한 이유는 상속하는 개체가이를 피할 수 없도록 final로 만드는 것입니다.
나는해야한다고 생각하지 않습니다. 을 시도하십시오. 클래스 레벨 javadoc에 하위 클래스가해야 할 것과하지 않아야한다고 생각하는지 기록해 둡니다. 누군가가 그 조언을 무시하고 수업을 수행하기로 결정했다면, 그 결과를 다루는 것이 그들의 문제입니다.
특정 방법으로 서브 클래스를 구현하기 위해 다른 사람을 강제로 시도의 문제가 다르게 일을하도록 필요하다는 것을 그들은 당신이 할 수있는 위치에 있지 않은 이유 ... 유스 케이스를 가질 수 있다는 것입니다알다. 미래 개발자에게 원하는 것을 할 수있는 자유를 남겨두고 결과에 대한 책임을지게하는 것이 더 좋은 생각입니다. 당신의 방법은 objectInputStream.readObject()에 의해 호출하기 위해서는
나는 귀하의 원칙에 일반적으로 동의합니다. 그러나 직렬화 프록시를 사용하기 시작하면, 제공하는 보안을 유지하고 '판도라의 상자를 다시 열지 말 것'이라고 믿습니다. – JVerstry
, 당신은 개인 선언해야합니다 :
당신이 당신의 메서드가 호출되지 않는 경우private void readObject(ObjectInputStream objectInputStream)
(거기에 브레이크 포인트를 넣어 이것을 증명하기 위해). 코드가 작동하는 것처럼 보일 수도 있지만 기본 직렬화가 사용 중이기 때문입니다.
서브 클래 싱을 허용하도록 보호하려고 할 수 있지만 필요하지는 않습니다. 직렬화 프로세스는 concrete 클래스의 readObject를 호출하기 전에 기본 클래스의 readObject를 자동으로 호출합니다. 콘크리트 클래스에서 호출하지 않아도 발생합니다.
objectInputStream.defaultReadObject();
... 내가 웹에서 읽은 다른 게시물과 반대입니다. writeObject 메소드에도 똑같이 적용됩니다.
아니요. 이 메서드를 public으로 만들려는 유일한 이유는 상속하는 개체가이를 피할 수 없도록 최종적으로 만드는 것입니다. InvalidObjectException을 throw합니다. 직렬화 프록시 사용을 강요하고 싶습니다. 나는 여기서 어떤 위험도 감수하지 않을 것이라고 생각한다. – JVerstry