2013-07-23 6 views
11

In Java erweitern die Collection-Schnittstellen Serializable aus mehreren guten Gründen nicht. Darüber hinaus implementieren die meisten gängigen Implementierungen dieser Schnittstellen Serializable.Java: Wie man serialisierbare Sammlungen sicherstellen kann

So Objekte, die eine der Erfassungs-Schnittstellen implementieren sind serializable wenn die Umsetzung selbst serialisierbar ist (was in der Regel der Fall ist) und, wenn die Objekte in der Sammlung alle serializable sind.

Aber wie kann ich sicherstellen, dass diese beiden Bedingungen erfüllt sind? Ich möchte nicht auf einen Laufzeitfehler stoßen, da der Compiler diese Bedingungen überprüfen könnte. Ich denke an einigen offensichtlichen Schnittstelle wie (Schaufenster für die List-Schnittstelle):

public interface SerializableList<T extends Serializable> extends Serializable, List<T> {} 

Ich frage mich, wenn niemand sonst dieses Problem konfrontiert ist, und kam mit dieser einfachen Lösung auf. Bisher konnte ich dazu weder eine Lösung noch eine Diskussion finden, was mich an meiner Idee zweifeln lässt.

+0

Sie können Ihren 'List'-Verweis als -' List ', wenn ich Ihre Frage richtig verstehe. Sie müssen keine eigene Benutzeroberfläche einrichten. –

+0

Der Compiler kann das nicht überprüfen. Jede Klasse, die Serializable implementiert, könnte ein nicht vorübergehendes, nicht serialisierbares Feld enthalten, das zu einer Laufzeitausnahme führen würde. Und eine ArrayList könnte serialisierbar sein, wenn die darin enthaltenen Objekte serialisierbar sind. Wenn das wirklich wichtig ist, verwenden Sie Komponententests. –

+1

@RohitJain: Ihr Vorschlag garantiert nur, dass die Objekte in der Liste serialisierbar sind, aber nicht die List-Implementierung selbst. – MrD

Antwort

6

Was fragen Sie im Wesentlichen für eine Typdefinition Verbinden von zwei Typen:

<type-def> a = null;

Was Sie brauchen, ist ein Ersatz von <type-def> mit einer Spezifikation, darauf achten, dass das von a referenzierte Objekt sowohl Serializable implementiert als sowie Collection<? extends Serializable>. Eine solche Typdefinition wird von der Java-Sprache nicht unterstützt.

Wie Sie bereits geschrieben, die naheliegendste Lösung kann sein, eigene Schnittstelle zu erklären, diese beiden anderen Schnittstellen verbindet:

interface SerializableCollection<T extends Serializable> extends Collection<T>, Serializable {}

Scheint ok, bis Sie so etwas wie dies versuchen:

SerializableCollection<String> a = new ArrayList<String>();

Dies wird jedoch nicht kompilieren. Auch wenn ArrayList<String> sowohl Collection<? extends Serializable> als auch Serializable implementiert, implementiert die Klasse SerializableCollection<String> nicht.

Jetzt können Sie, wenn Sie würde, umgehen auch dieses Problem durch eine neue Klasse erklärt:

SerializableArrayList<T extends Serializable> extends ArrayList<T> implements SerializableCollection<T> {}

Jetzt haben Sie im Wesentlichen kombiniert alles, was Sie benötigen und wäre in der Lage, die ursprüngliche Anforderung zu erfüllen:

SerializableCollection<String> a = new SerializableArrayList<String>();

Ist es die Mühe wert? In deinem Fall musst du dich entscheiden, aber ich würde nein sagen.Mein Argument ist, dass, da der Serializable Marker nur ein non-formales "Label" ist, die Gewährleistung, dass sowohl Ihre Sammlung als auch ihr Inhalt Serializable implementieren, noch nicht garantiert, dass die Sammlung und ihr Inhalt serialisiert werden können.

+1

Danke. Ich denke, jetzt ist alles klar für mich. Wie Sie und JB Nizet festgestellt haben, kann ich nicht darauf vertrauen, dass Objekte, die die 'Serializable'-Schnittstelle implementieren, wirklich serialisierbar sind (es ist schade). Ich denke, das ist der Punkt: Lohnt es sich? Ich werde darüber nachdenken, ob es in meinem Fall anwendbar ist. – MrD

6

Serializable ist keine großartige Schnittstelle. Es hätte eine Anmerkung sein sollen, wenn diese bei der Implementierung verfügbar waren.

Wie würden Sie mit einem List eines List von etwas nicht Serializable umgehen. Sie müssen sicherstellen, dass kein Objekt nicht serialisierbar ist. Nicht alle Objekte, die Serializable implementieren, können tatsächlich serialisiert werden.

+0

Also gibt es keine Möglichkeit, eine Kompilierzeitprüfung dafür zu machen? –

+0

'Schnittstelle SerializableCollection > {} 'kann sowas gemacht werden? –

+1

Eine 'List' von Objekten, die nicht 'Serializable' sind, kann nicht zur' SerializableList' hinzugefügt werden, da diese 'List' nicht' Serializable' implementiert. Natürlich könnte ich eine 'ArrayList' (die serialisierbar ist) hinzufügen, die einige nicht serialisierbare Objekte enthält - aber nur, wenn ich sie als unformatierten Typ verwende. Wenn es parametrisiert ist, sollte der Compiler darüber beschweren. – MrD

0

Ein Ansatz für eine Sammlung Klonen und enthaltenen Objekte sind

import org.apache.commons.lang3.SerializationUtils; 
... 
ClonedArrayList = SerializationUtils.deserialize(SerializationUtils.serialize(OriginalArrayList)) 

(zum Beispiel über Arraylist mit <Typ> (Sammlung), weil SerializationUtils müssen die Serializable-Schnittstelle)

Grüße, Gunnar

Verwandte Themen