2009-03-24 12 views
7

Gibt es eine Lösung, um eine letzte Variable in einem Java-Konstruktor zu verwenden? Das Problem ist, dass, wenn ich ein letztes Feld initialisieren wie:Letzte Variable vor dem Konstruktor in Java initialisieren

private final String name = "a name"; 

dann kann ich es nicht im Konstruktor verwenden. Java führt zuerst den Konstruktor und dann die Felder aus. Gibt es eine Lösung, mit der ich auf das letzte Feld im Konstruktor zugreifen kann?

+1

Ich nehme an, dass Sie den Wert für den Konstruktor richtig ändern möchten? – webclimber

+2

Ich stimme zu schließen, weil es aus meinem Verständnis heraus ergibt, dass dies überhaupt kein Problem ist. Was das OP zu tun versucht, sollte funktionieren. –

+1

Der Konstruktor führt implizit die Feldinitialisierung unmittelbar vor dem Aufruf des Superkonstruktors aus. –

Antwort

17

Ich verstehe Ihre Frage nicht wirklich. Das

public class Test3 { 
    private final String test = "test123"; 

    public Test3() { 
     System.out.println("Test = "+test); 
    } 

    public static void main(String[] args) { 
     Test3 t = new Test3(); 
    } 
} 

führt wie folgt:

$ javac Test3.java && java Test3 
Test = test123 
15

Sie die Initialisierung im Konstruktor, zB

private final String name; 
private YourObj() { 
    name = "a name"; 
} 

Natürlich, wenn Sie tatsächlich den Wert bei Variablendeklaration Zeit kennen, macht es mehr Sinn es eine Konstante, zum Beispiel

private static final String NAME = "a name"; 
zu machen
2

In diesem Fall können Sie das Feld auch als 'statisch' markieren.

+0

ein Weg ohne ein statisches Feld? – Tobias

+0

@ Tobiask: Warum willst du kein statisches Feld? – sfossen

+0

Es ist unveränderlich, also können Sie es auch statisch machen. –

1

In diesem Fall können Sie es auch statisch machen. Und Java-Konvention besteht darin, solche Konstanten in ALL_CAPS zu benennen.

1
private static final String name = getName(); 

wo getName() ist eine statische Funktion, die Sie den Namen bekommt.

+0

Vorsicht vor diesem Konstrukt, wenn getName() etwas anderes als eine Konstante zurückgibt. Sie können feststellen, dass die von getName() verwendete Logik möglicherweise nicht initialisiert wurde. – DJClayworth

3

Wenn Sie es statisch markieren, können Sie es im Konstruktor verwenden, aber da Sie es endgültig festgelegt haben, kann es nicht geändert werden.

private static final String name = "a_name"; 

ist es möglich, einen statischen init Block zu verwenden.

private static final String name; 

static { name = "a_name"; } 

Wenn Sie versuchen, den Wert im Konstruktor zu ändern, dann können Sie keinen Standardwert zuweisen oder Sie müssen es nicht endgültig machen.

private String name = "a_name"; 
Foo(String name) 
{ 
    this.name = name; 
} 

oder

private final String name; 

Foo(String name) 
{ 
    if(s == null) 
     this.name = "a_name"; 
    else 
     this.name = name; 
} 
0

ich es nicht im Konstruktor verwenden können, während Java mit dem Konstruktor läuft ein dann die Felder ...

Dies ist nicht korrekt, Felder werden zuerst ausgewertet, sonst könnten Sie auf keine Standardwerte von Membern in Ihren Konstruktoren zugreifen, da sie nicht initialisiert würden. Diese tut Arbeit:

public class A { 
    protected int member = 1; 
    public A() { 
     System.out.println(member); 
    } 
} 

Das Schlüsselwort letzte lediglich das Element konstant markiert, es anders als jedes andere Mitglied behandelt wird.

EDIT: Versuchen Sie Set den Wert im Konstruktor?Das würde nicht funktionieren, da das Mitglied unveränderlich ist, wenn es als endgültig definiert wird.

+0

Technisch ist es der Konstruktor, der (implizit) die Feldinitialisierungslogik ausführt. –

+0

Nun, ok. Die Felder werden dennoch zuerst ausgewertet. – soulmerge

2

Eine andere Möglichkeit ist es, das Feld in einer Instanz Initialisierungsblocks zu initialisieren:

public class Foo { 
     final String bar; 

     { 
       System.out.println("initializing bar"); 
       bar = "created at " + System.currentTimeMillis(); 
     } 

     public Foo() { 
       System.out.println("in constructor. bar=" + bar); 

     } 

     public static void main(String[] args) { 
       new Foo(); 
     } 
} 
5

Wir bekommen von der Frage entfernt.

Ja, Sie können eine private final Variable verwenden. Zum Beispiel:

public class Account { 
    private final String accountNumber; 
    private final String routingNumber; 

    public Account(String accountNumber, String routingNumber) { 
     this.accountNumber = accountNumber; 
     this.routingNumber = routingNumber; 
    } 
} 

Dies bedeutet, dass die Account-Klasse eine Abhängigkeit von den zwei Zeichenfolgen, Konto und Routing-Nummern hat. Die Werte dieser Klassenattribute MÜSSEN festgelegt werden, wenn die Klasse Account erstellt wird, und diese Anzahl kann nicht geändert werden, ohne eine neue Klasse zu erstellen.

Der 'letzte' Modifikator macht die Attribute unveränderlich.

+2

Im Prinzip erhalten Sie eine Einstellung für die Werte im Konstruktor. Nach Abschluss des Konstruktors sind die Attribute konstant. –

+2

Ich bekomme einen Fehler "kann dem letzten Variablenwert keinen Wert zuweisen". –

Verwandte Themen