2009-03-24 14 views
7

Czy istnieje rozwiązanie do zastosowania zmiennej końcowej w konstruktorze Java? Problem polega na tym, że jeśli zainicjować końcową boiska jak:Inicjowanie zmiennej końcowej przed konstruktorem w Javie

private final String name = "a name"; 

wtedy nie można go używać w konstruktorze. Java najpierw uruchamia konstruktor, a następnie pola. Czy istnieje rozwiązanie, które pozwala mi uzyskać dostęp do końcowego pola w konstruktorze?

+1

Zakładam, że chcesz zmienić wartość na konstruktorze, prawda? – webclimber

+2

Głosuję, aby zamknąć, ponieważ, z mojego zrozumienia, okazuje się, że to wcale nie jest problem. Co powinien zrobić OP, powinno działać. –

+1

Konstruktor niejawnie wykonuje inicjalizację pola bezpośrednio przed wywołaniem super konstruktora. –

Odpowiedz

17

Nie bardzo rozumiem twoje pytanie. Że

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(); 
    } 
} 

wykonuje się następująco:

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

Czy inicjowanie w konstruktorze, np

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

Oczywiście, jeśli faktycznie znają wartość w zmiennej czasu deklaracji, to więcej sensu, aby to stała, np

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

W tym przypadku można również oznaczyć to pole jako "statyczne".

+0

sposób bez pola statycznego? – Tobias

+0

@Tobiask: Dlaczego nie chcesz statycznego pola? – sfossen

+0

Jest niezmienny, więc równie dobrze możesz go ustawić statycznie. –

1

W takim przypadku możesz równie dobrze zrobić to statycznie. Konwencja Javy ma nazywać takie stałe w ALL_CAPS.

1
private static final String name = getName(); 

gdzie getName() jest statyczna funkcja, która dostaje nazwę.

+0

Uważaj na tę konstrukcję, jeśli funkcja getName() robi coś innego niż zwracanie stałej. Możesz znaleźć logikę używaną przez funkcję getName(), która nie została zainicjalizowana. – DJClayworth

3

Zaznaczenie go jako statycznego, pozwoli na użycie go w konstruktorze, ale ponieważ dokonano go jako ostatecznego, nie można go zmienić.

private static final String name = "a_name"; 

jest również możliwe użycie statycznego bloku inicjalizacyjnego.

private static final String name; 

static { name = "a_name"; } 

Jeśli próbujesz zmienić wartość w konstruktorze, to nie można przypisać wartość domyślną lub trzeba zrobić to nie ostateczna.

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

lub

private final String name; 

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

nie mogę użyć go w konstruktorze, a java pierwszy uruchamia konstruktora następnie pola ...

To nie jest poprawne, pola są najpierw oceniane, w przeciwnym razie nie można uzyskać dostępu do wartości domyślnych członków w konstruktorze, ponieważ nie zostaną one zainicjowane. Ten robi praca:

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

Słowo kluczowe końcowy jedynie wyznacza stałą członkowskim, jest on traktowany jak każdy inny członek inaczej.

EDYCJA: Czy próbujesz ustawić wartość wartość w konstruktorze?To nie zadziała, ponieważ członek jest niezmienny, jeśli zostanie zdefiniowany jako ostateczny.

+0

Technicznie jest to konstruktor, który (niejawnie) wykonuje logikę inicjalizacji pola. –

+0

Dobrze, dobrze. Pola są jednak najpierw oceniane. – soulmerge

2

Kolejna możliwo jest zainicjować pole w bloku wystąpienie inicjatora:

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

Dostajemy od pytania. Można używać zmiennej private final. Na przykład:

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

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

Co oznacza, że ​​klasa Konto ma zależność od dwóch łańcuchów, numerów kont i tras. Wartości tych atrybutów klas MUSZĄ być ustawione podczas konstruowania klasy Konto, których nie można zmienić bez utworzenia nowej klasy.

"Ostateczny" modyfikator sprawia, że ​​atrybuty są niezmienne.

+2

Zasadniczo uzyskujesz jeden zastrzyk przy ustawianiu wartości w konstruktorze. Po zakończeniu konstruktora atrybuty są stałe. –

+2

Pojawia się błąd "nie można przypisać wartości do końcowej wartości zmiennej". –