2012-10-11 2 views
14

Java enthält viele Klassen (wie in Swing), die die dreaded and error proneinterface Serializable implementieren.Was ist ein guter Weg, um eine Klasse unserialisierbar zu machen?

Wenn Sie implementieren, sagen wir, ein neues TableModel von AbstractTableModel erstreckt, das neue Modell serializable sein muss, aber was, wenn es interne Datentypen enthält, die nicht serialisierbar sind und die müssen nicht sein, da Sie nicht planen Sie um diese Funktion trotzdem zu nutzen? In diesem Fall werden Werkzeuge wie Sonar verrückt. Die entweder beschweren, dass "Klasse Foo Nicht-transiente nicht serialisierbare Instanz Feld bar definiert".

Also mache ich das Feld transient nur um „Das Feld Foo.bar vergänglich ist, aber nicht durch Deserialisierung gesetzt“

Ist es möglich, zu sagen: „Nein, diese Klasse nicht serialisierbar ist, und I don‘ Ich will, dass es so ist, dass Sie keine Fehler in Werkzeugen wie Sonar bekommen?

+0

Does Sonar Unterstützung Unterdrückung einer Warnung für eine einzelne Klasse? In IntelliJ gibt es die Möglichkeit, der Klasse für diese Prüfung ein @SuppressWarning hinzuzufügen. –

+0

Sonar führt nur FindBugs, PMD und CheckStyle auf Ihrem Code aus und aggregiert die Ergebnisse. Eine Lösung, die diese drei ruhig hält, würde für mich funktionieren. '@ SuppressWarning' funktioniert wie erwartet. Es gibt auch Plugins, die es erlauben, Warnungen durch Dinge wie Dateiname, Pfad oder Stringmuster zu ignorieren. –

+0

Ist das nicht, wofür 'transient' ist? – EJP

Antwort

20

von diesen JavaRevisited article Zitiert (siehe # 8):

Java Serialisierung Sie müssen vermeiden write() und readObject-() -Methode in Ihrer Klasse und NotSerializableException von jenen Verfahren werfen implementieren müssen.

So brauchen Sie nur diese in Ihre Klasse einzufügen:

private void writeObject(java.io.ObjectOutputStream stream) throws java.io.IOException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 

private void readObject(java.io.ObjectInputStream stream) throws java.io.IOException, ClassNotFoundException { 
    throw new java.io.NotSerializableException(getClass().getName()); 
} 
+0

Wow, wusste nicht über 'NotSerializableException' – AlexR

+0

Ich verifizierte diese Lösung und es funktioniert. Sonar, FindBugs und PMD scheinen alle nach "NotSerializableException" zu suchen. –

+2

Klingt komisch: Implementieren Sie ein Interface Serializable und werfen Sie beim Serialisieren eine NotSerializableException. Der einzige Weg, den ich sehe, ist, eine Proxy-Klasse zu erstellen, die NICHT serialisierbar ist und alle Methoden an die konkrete Implementierung delegiert. Aber das ist so etwas wie ein winziger kleiner Vogel. –

0

Ich denke über kann werfen Implementierungsmethode private void writeObject(), wie folgend:

private void writeObject(ObjectOutputStream oos) throws IOException { 
    throw new UnsupportedOperationException("Not serializable!!!"); 
} 

Alternativ können Sie Externalizable und schreiben similiar Implementierung von writeExternal()

Beide sind implementieren nicht „gut“ Methoden, sondern nur Workarounds.

1

Die Antworten, die ich hier sehe, beantworten nur die Frage, ob es möglich ist, die Serialisierung oder Deserialisierung einiger serialisierter Klassen zu verhindern. Die Frage war jedoch eine andere:

'Ist es möglich zu sagen "Nein, diese Klasse ist nicht serialisierbar, und ich will es nicht sein" in einer Weise, dass Sie keine bekommen Fehler in Werkzeugen wie Sonar?

(So frage ich mich über die vielen up-Stimmen auf diesen Antworten ...)

um die Antwort Google'ing scheint ‚Nein‘ zu sein, kann Sonar gesagt werden, dass eine solche Klasse ein „false ist positiv ", aber das erfordert, an Sonar zu basteln. Entwickler, die Code entwickeln, der von Sonar anderer Leute überprüft wird, können nicht von dieser Möglichkeit profitieren.

Und da die Frage tatsächlich nach einer Lösung für andere Werkzeuge wie "Sonar" verlangt, kann die Antwort im Allgemeinen nicht "Ja" sein - sicher wird ein solches Werkzeug darauf bestehen "implementiert Serializable + hat nicht serialisierbares nicht transientes Feld "bedeutet Ärger.

+1

sie bekommen Upvotes, weil sie eine Lösung vorschlagen. – Matsemann

+0

Oh, ich sehe, das Original-Poster hat es versucht und die fraglichen Tools suchen tatsächlich nach dieser Ausnahme. Die Antworten bedeuten also eine Lösung ... – mkl

1

Sie können so etwas verwenden?

@SuppressFBWarnings(justification = "This field need to be transient") 
private transient SomeObject myTransientField; 

Sie unterdrücken die Findbug-Warnung. Sie können auch den Prüfungstyp geben Sie an, wie auf suprres wollen:

@SuppressFBWarnings("SE_TRANSIENT_FIELD_NOT_RESTORED") 

Die komplette Liste gibt es: http://findbugs.sourceforge.net/bugDescriptions.html

+0

Ich sehe, was Sie versuchen zu tun, aber ich habe nur "transient", weil FindBugs sich darüber beschwert, dass das Feld nicht serialisierbar ist. Was ich suche, ist eine Möglichkeit, Sonar zu sagen, dass die Klasse nicht serialisiert werden kann und wird. –