2016-05-18 9 views
0

Ich habe einen Anwendungsfall, wo ich zuerst ein (veränderbares) Objekt erstellen muss, und in einem bestimmten Szenario muss ich es unveränderlich machen (ich will es nicht unveränderlich machen). Gibt es einen guten Weg, dies zu erreichen? Die Anforderung ist Änderung es von veränderbar zu unveränderlich zu einer bestimmten Zeit, mit endgültigen wird nicht funktionieren.Wie man ein veränderliches Objekt zu unveränderlich macht? (nicht bei der Erstellung)

+6

mögliches Duplikat von http://stackoverflow.com/questions/18194139/make-immutable-java-object –

Antwort

-1

Kurz gesagt: Alle Mitglieder müssen als final deklariert werden und alle Memebertypen müssen auch unveränderlich sein.

+0

das ist nicht, was ich frage ... Auf diese Weise wird das Objekt als unveränderlich erstellt, aber meine Anforderung ist irgendwann, ich kann es unveränderlich machen. –

+0

Und die Klasse muss Unterklassen verbieten. Andernfalls können Sie eine änderbare Unterklasse erstellen. –

2

Ein Objekt kann nicht gleichzeitig veränderlich und unveränderlich sein. Sie können eine Methode in Ihrem veränderbaren Objekt verwenden, um das entsprechende unveränderbare Objekt zurückzugeben.

Hier ist ein Beispiel für die Umsetzung von dem, was ich sage.

class BasicMutable { 
    private int i; 

    public void setI(int i){ 
     this.i = i; 
    } 

    public void getI(){ 
     return i; 
    } 

    public BasicImmutable getImmutable(){ 
     return new BasicImmutable(this); 
    } 
} 

Jetzt unveränderliches Objekt erstellen

class BasicImmutable { 
    private final i; 

    BasicImmutable(BasicMutable bm){ 
     this.i = bm.i; 
    } 

    public void getI(){ 
     return i; 
    } 
} 

Sie können auch eine getMutable() Methode in BasicImmutable müssen veränderbares Objekt erhalten entspricht.

+0

yap, das ist eine Lösung, die ich auch gefunden habe. Ich denke, ist es möglich, ein unveränderliches Objekt durch eine veränderbare zu bauen, irgendeine Bibliothek, die wir benutzen können? –

+0

Es gibt keine Bibliothek, soweit ich weiß, um Ihre benutzerdefinierte Klasse zur Laufzeit unveränderlich zu machen und wann immer Sie möchten auf veränderbar zu sein. – afzalex

+2

Dies ist im Wesentlichen das Builder-Muster. – shmosel

0

Es gibt eine Reihe von Bibliotheken, die die Arbeit für Sie erledigen könnten (ich habe sie nicht selbst benutzt).

https://github.com/verhas/immutator [1]

http://immutables.github.io [2]

Beide Bibliotheken haben ihre Vor- und Nachteile.

[1] scheint sehr leicht und einfach zu sein und erlaubt Ihnen, Ihre eigene Query Schnittstelle (die die unveränderlichen Methoden definiert) zu definieren.

[2] scheint sehr ausgereift zu sein und verfügen über vollständig und Bauherren, JSON/Gson Unterstützung usw.

+0

Wie vergleichen sie mit Guava's immutableXXX? –

+0

Sie sind nicht nur auf Sammlungen beschränkt. –

0
public class Mutable { 
    private int member; 

    public Mutable(int member) { 
    this.member = member; 
    } 

    public int getMember() { 
    return member; 
    } 

    public void setMember(int member) { 
    this.member = member; 
    } 
} 

public class ImmutableWrapper extends Mutable { 

    private Mutable mutable; 

    public ImmutableWrapper(Mutable mutable) { 
    super(0); // dummy filling 
    this.mutable = mutable; 
    } 

    @Override 
    public int getMember() { 
    return mutable.getMember(); 
    } 

    @Override 
    public void setMember(int member) { 
    throw new UnsupportedOperationException(); 
    } 
} 


public static void main(final String[] args) { 
    Mutable mutable = new Mutable(1); 
    mutable = new ImmutableWrapper(mutable); 
    mutable.getMember(); 
    try { 
     mutable.setMember(8); 
    } catch (final Exception e) { 
     System.out.println(e); 
    } 
} 

Ausgang:

java.lang.UnsupportedOperationException

+0

Ich mag die Kopplung in dieser Lösung nicht. Wenn Mutable mit einer neuen Mutationsmethode aktualisiert wird, muss der Entwickler wissen, dass er auch ImmutableWrapper ändern muss. – Stormcloud

+0

Ich denke, diese Idee ist ähnlich wie die Implementierung von Guava's immutableXXX? Wir bekommen eine nicht unterstützte Exception, damit wir sie fangen und verarbeiten können, cool! –

+0

Ja, das soll nur die Grundidee demonstrieren.Als allgemeine Lösung kann ein dynamischer Proxy verwendet werden. –