2009-07-02 16 views
5

Gibt es eine Möglichkeit in Java, dass eine Aussage wieIn Java, ist neu immer neu?

Thing thing = new Thing(); 

konnte nicht Ergebnis in einem neuen Objekt (das heißt, dass jede mögliche Weise thing zu einem bereits vorhandenen Objekt nach oben zeigen enden könnte) geschaffen werden?

+2

Warum fragen Sie? Hast du irgendwo merkwürdiges Verhalten? –

+2

Kein seltsames Verhalten. Nur neugierig - ich las über den Integer (int i) -Konstruktor - der Punkt, der gemacht wurde, war, dass die statische Methode Integer.valueOf (int i) besser sein könnte, da sie Objekte bei Bedarf wiederverwenden wird - ich wollte überprüfen, dass es unmöglich war , nicht nur unkonventionell, für einen Konstrukteur, der die Wiederverwendung macht. –

+8

Ja, es ist unmöglich. In C++ könnten Sie den 'new'-Operator überschreiben, aber Sie können nicht in Java. Was mich nicht traurig macht. –

Antwort

16

Der Operator new weist neuen Heapspeicher zu und ruft den Konstruktor auf. Auf diese Weise erhalten Sie immer ein neues Objekt (es sei denn, wie bereits erwähnt, wird im Konstruktor eine Exception ausgelöst).

Die Sache ist ein wenig anders mit statischen Methoden, die eine Referenz zurückgeben, wie Integer.valueOf() die Objekte aus einem internen Pool wenn möglich wiederverwendet.

+1

Yep und es ist sogar ein empfohlenes Muster in der großen Joshua Bloch "Effektive Java" –

6

Wenn der Konstruktor für Thing eine Ausnahme auslöst, wird das Objekt nicht erstellt. thing wird jedoch nie auf eine andere vorhandene Instanz von Thing verweisen.

+0

noch 'null' Werte. Es ist seltsam, Code wie 'Thing t = new Thing() zu sehen; if (t == null) ... '- es wird nie passieren –

0

Nein, für den Fall, dass kein Speicherplatz im Speicher vorhanden ist, sollten Sie einen OutOfMemoryError erhalten.

Natürlich könnten vom Thing-Konstruktor andere Ausnahmen ausgelöst werden.

+0

hmmm, warum ist das nicht ein OutOfMemoryError? Nur interessiert. –

+0

die richtige Ausnahme ist wirklich OutOfMemoryError. – cd1

+0

@ CD1 @Tim Korrigiert den Fehler. Ich wusste, dass es so etwas war. Meine schlechten –

0

Ich bin mir nicht sicher, ob ich Ihre Frage richtig verstehe.

Die Definition von Neu ist , um ein neues Objekt zuzuweisen und zu initialisieren.

Ich denke, Sie könnten in der Lage sein, eine statische Referenz auf ein Objekt zu speichern, und dann klonen, um ein neues Objekt zu erstellen, aber dieses Objekt wäre immer noch neu.

Da Sie den Wert von this nicht ändern können (sonst könnten Sie einfach etwas wie this = oldObject in Ihrem Konstruktor sagen), die einzige Möglichkeit, dies zu tun ist, eine Ausnahme zu werfen, wie zuvor erwähnt wurde.

0

so weit ich weiß, es ist nicht wie C++, wo Sie operator new überlasten oder neue oder andere Zuordnungs-Dinge platzieren können. (aber ich kenne die JLS nicht)

3

Die Verwendung von new führt immer dazu, dass ein neues Objekt zugewiesen und erstellt wird. Möglicherweise verweisen Sie jedoch auf das Konzept internieren, wo Objekte und in einem Pool gespeichert und wiederverwendet werden können, um Platz zu sparen. Ein gutes Beispiel finden Sie in diesem Artikel unter String interning in Java.

1

Neu ist immer neu (vielleicht mit einigen Ausnahmen für primitive Wrapper), aber wenn die Wiederverwendung von Objekten ein gewünschtes Verhalten ist, gibt es Möglichkeiten, dies durch bestimmte Entwurfsmuster (Singleton, Factory, Pool usw.) zu tun.

+1

Primitive Wrapper (auch Boxed Primitive genannt) folgen denselben Regeln wie jede andere Klasse: Wenn Sie einen Konstruktor verwenden, um einen zu erstellen, erhalten Sie immer eine neue Instanz. Autoboxing erstellt jedoch nicht jedes Mal ein eindeutiges Objekt, da es eine Factory-Methode anstelle eines Konstruktors verwendet. –

+0

Habe ich etwas anderes gesagt? – quosoo

+1

Neu ist immer neu. Es gibt keine Ausnahmen, auch nicht für primitive Wrapper. – dave4420

-1

In Java ist das Einzige, was mir einfällt, das Singleton-Muster. Dies würde nicht mehrere neue Instanzen von Thing erzeugen, sondern jedes Mal eine Instanz desselben Objekts.

+1

Jedes Mal, wenn Sie 'new' verwenden, erstellen Sie eine neue Instanz. Zeitraum. Mit dem Singleton-Muster rufen Sie 'SingletonClass.getInstance()', nicht 'new SingletonClass()' auf. –

4

Mehrere Leute sagen, dass ein Objekt nicht erstellt wird, wenn der Konstruktor eine Ausnahme auslöst. Ich möchte nur darauf hinweisen, dass dies nicht wahr ist.Als Beispiel nehmen Sie einen Blick auf diesen sehr schlechten Code:

public class Test { 
    static int count; 

    static Set<Test> set = new HashSet<Test>(); 

    int id = count++; 


    public Test() { 
     set.add(this); 
     throw new RuntimeException(); 
    } 


    public static void main(String[] args) throws Exception { 
     for(int i = 0; i < 5; i++) { 
      try { 
       new Test(); 
      } catch(Exception e) { 
      } 
     } 
     System.out.println(set); 
    } 


    public String toString() { 
     return "Test[" + id + "]"; 
    } 
} 

Die Ausgabe lautet:

[Test[0], Test[1], Test[2], Test[4], Test[3]] 

new erstellt ein neues Objekt zu jeder Zeit.

0

new erstellt immer ein neues Objekt. In Java können Sie Objekte nicht erneut verwenden. Dies führt wirklich zu Performance-Problemen in bestimmten Java-Klassen. Für z.B. Die Boolesche Klasse kann praktisch nur zwei Werte speichern (wahr oder falsch), trotzdem kann ein Benutzer mehrere Objekte mit demselben Wert unter Verwendung von new erstellen.

0

No.

nach dieser Zeile von Code ausgeführt thing wird nie ein Objekt verweisen, das vor dieser Zeile vorhanden war.

0

Der Aufruf von new kann fehlschlagen, wenn Sie zum ersten Mal auf die Klasse verweisen und wenn die Klasse statische Blöcke aufweist, die nicht initialisiert werden können. Ich habe Verhaltensweisen erlebt, bei denen Laufzeitfehler, die in einem statischen Block oder Konstruktor auftreten, dazu führen, dass der neue Aufruf eine ClassNotFound-Ausnahme im Kontext der Verwendung innerhalb des Websphere-Anwendungsservers auslöst. Der Websphere-Klassenlader lehnt die Klasse wegen der Laufzeitausnahme anscheinend vom Laden ab.