2016-11-01 2 views
0

Ich komme aus anderen Sprachen zu Java, also bitte vergib mir, wenn das offensichtlich ist, aber ich habe ein sehr seltsames Verhalten angetroffen.Java Singleton löst manchmal NullPointerException

Ich schreibe eine einfache Pig UDF. Ich gebe ein Tuple-Objekt zurück, das ich mit einem TupleFactory-Singleton erstellt habe. In den folgenden zwei Codebeispielen funktioniert das erste Beispiel, während das zweite eine NullPointerException auslöst, wenn das newTuple erstellt;

public class MyUDF { 

    public Tuple func(Tuple input) { 
     return TupleFactory.getInstance().newTuple(Arrays.asList(o1, o2, o3)); 
    } 
} 

public class MyUDF { 
    ... 
    TupleFactory _factory; 

    public Tuple func(Tuple input) { 
     _factory.getInstance(); 
     return _factory.newTuple(Arrays.asList(o1, o2, o3)); 
    } 
} 
+0

dass bcz, das Sie bearbeiten, _factory.getInstance() gibt eine neue Instanz zurück, die nicht an _factory instance zurückgegeben wird – mhasan

Antwort

1

Ihr erster Code TupleFactory.getInstance() ist eine statische Klasse Methode für die Klasse, die sich selbst, wie es für eine Singleton-Muster Umsetzung zu erwarten war.

aufrufen Instanzmethode ohne eine Instanz

Ihre zweite Code _factory.getInstance() auf eine Instanzvariable anruft, eine Klasse Element, das definiert, aber noch nicht instanziiert. Sie können keine Objektmethode für ein Objekt aufrufen, das nicht existiert.

Enum als Singleton

schließlich der beste sicherste einfachste Weg, um die Singleton-Muster in Java zu implementieren, ist durch eine Enumeration. Search Stack Overflow und/oder eine Suchmaschine für Wörter wie: Java singleton enum Joshua Bloch "Effektives Java".

public enum TupleFactory { 
    INSTANCE; 

    // Add private constructor if needed. 

    public Tuple makeTuple(…) { 
     … 
     return tuple ; 
    } 

} 

Dies ist einfach.

Tuple t = TupleFactory.INSTANCE.makeTuple(…) ; 

von Hüten Sie sich vor Missbrauch von Singleton

Schließlich werde ich die obligatorische Vorsicht über Singleton hinzufügen oft ein „Codegeruch“ zu sein, ein Symptom für schlechte Konstruktion aus einem Mangel an Verständnis von Objektstamm -orientierte Programmierung.

0

müssen Sie _factory.getInstance() speichern; Ausgabe zuerst als Tupelinstanceclass obj = _factory.getInstance(); Rückgabe obj.newTuple (Arrays.asList (o1, o2, o3));

0

Ich glaube, Sie zu

public class MyUDF { 
... 
TupleFactory _factory; 

public Tuple func(Tuple input) { 
    _factory = TupleFactory.getInstance(); 
    return _factory.newTuple(Arrays.asList(o1, o2, o3)); 
} 
} 
0

Vom ersten Stück Code ändern sollte, kann ich daraus schließen, dass die getInstance() Methode static ist. Der wichtige Punkt, der über die Methoden static zu beachten ist, ist, dass Sie nicht mit Klassenobjekten darauf zugreifen sollten. Stattdessen sollten Sie mit Klassennamen auf sie zugreifen, da es sich um Klassenmethoden handelt.

Die Grundidee hinter singletons ist, dass Sie zunächst eine Klassenmethode (keine Instanzmethode) nicht das Objekt der Klasse haben und die Sie anrufen, das Objekt dieser Klasse zu bekommen. Jetzt dein erstes Stück Code rechtfertigt es, aber im zweiten Teil des Codes hast du bereits _factory Objekt, also warum würdest du getInstance() anrufen, um das Objekt der Klasse zu erhalten.

Auch in dieser Zeile _factory.getInstance(), beachten Sie, dass _factory gerade deklariert wurden, aber nie initialisiert wurde, und das ist der Grund, warum Sie NullPointerException bekommen.

Siehe auch:

  1. What is the difference between class and instance methods?
  2. Java: when to use static methods

Der folgende Code funktioniert.

public class MyUDF { 
    TupleFactory _factory; 

    public Tuple func(Tuple input) { 
     _factory = TupleFactory.getInstance(); 
     return _factory.newTuple(Arrays.asList(o1, o2, o3)); 
    } 
} 
+0

Ich glaube, Ihre Aussage "Sie können nicht mit Klassenobjekten zugreifen" sollte geändert werden in "Sie sollten nicht Greife auf sie mit Klassenobjekten zu " – mhasan

+0

@mhasan danke, dass du darauf hingewiesen hast. –

Verwandte Themen