2016-06-18 8 views
0

ich eine Basisklasse haben wie dieseJava Klasse Instanziierung mit Block-

abstract class BaseClass { 
    protected Class<? extends iBase> _BASE = null; 

    protected static abstract class iBase {} 

    protected BaseClass() { 
     setBase(); 
    } 

    protected void setBase() { 
     // use reflection to find fields, but... 
     // _BASE is null? 
    } 
} 

und erweitern sie mit einer Klasse wie dieses

public class MyClass extends BaseClass { 
    { // what is this called? Anonymous Block Class Statements? 
     _BASE = iBase.class; 
    } // does this get called before constructor starts? 

    public static class iBase extends BaseClass.iBase { // yes, it is hiding super 
     public static final String someValue = ""; 
    } 

    public MyClass() { 
     super(); 
    } 
} 

, wenn ich die neue Klasse

instanziiert gehen
MyClass myClass = new MyClass(); 

_BASE ist null, warum? Ich setze es eindeutig

+0

Sie könnten die Klasse als Argument an den Konstruktor '' 'BaseClass'' übergeben. –

+0

// Wie heißt das? Anonyme Blockklassenanweisungen? - Dies sind Instanz (im Gegensatz zu statischen) Initialisierung Blöcke – Andreas

+0

@Dici Ursache mit Reflektion Ich kann die Felder der Unterklasse, Ursachen die Eltern-Sets keine – nuebKitsune

Antwort

2

Weil der Superklasse Konstruktor vor der Unterklasse Konstruktor heißt. So wird setBase() ausgeführt, bevor der Block _BASE in der Unterklasse initialisiert.

Der Aufruf einer ausschaltbaren Methode aus einem Basisklassenkonstruktor sollte vermieden werden, gerade wegen der Probleme, mit denen Sie konfrontiert sind. Und auch, wenn Sie es in der Unterklasse überschreiben, wird die überschriebene Implementierung für ein Objekt aufgerufen, das noch nicht richtig initialisiert ist.

+0

Das Debug zeigt das nicht an; Es wird angezeigt, dass _BASE gesetzt ist, und dann die Methode, die beim Durchlaufen ausgeführt wird. – nuebKitsune

+2

Dann ist Ihr Debugger falsch, oder Sie interpretieren nicht, was es richtig macht. Fügen Sie einfach println-Anweisungen überall hinzu, und Sie werden sehen (wenn die Tatsache, dass _BASE null ist, nicht genug ist, um Sie zu überzeugen). –