2009-03-24 40 views
7

Có giải pháp nào để sử dụng biến cuối cùng trong một hàm tạo Java không? Vấn đề là nếu tôi khởi tạo trường cuối cùng như:Khởi tạo biến cuối cùng trước khi hàm tạo trong Java

private final String name = "a name"; 

thì tôi không thể sử dụng nó trong hàm tạo. Java đầu tiên chạy hàm tạo và sau đó là các trường. Có một giải pháp cho phép tôi truy cập vào lĩnh vực cuối cùng trong constructor?

+1

Tôi giả định rằng bạn muốn thay đổi giá trị trên hàm tạo phải không? – webclimber

+2

Tôi đang bỏ phiếu để đóng vì, từ sự hiểu biết của tôi, nó chỉ ra điều này không thực sự là một vấn đề ở tất cả. Những gì OP đang cố gắng làm nên hoạt động. –

+1

Hàm khởi tạo ngầm thực hiện khởi tạo trường ngay lập tức trước khi gọi hàm tạo siêu. –

Trả lời

17

Tôi không thực sự hiểu câu hỏi của bạn. Đó

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

thực hiện như sau:

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

Làm khởi trong các nhà xây dựng, ví dụ,

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

Tất nhiên, nếu bạn thực sự biết giá trị vào thời điểm khai báo biến, nó có ý nghĩa hơn để làm cho nó một hằng số, ví dụ:

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

Trong trường hợp này, bạn cũng có thể đánh dấu trường là 'tĩnh'.

+0

một cách không có trường tĩnh? – Tobias

+0

@Tobiask: Tại sao bạn không muốn một trường tĩnh? – sfossen

+0

Nó không thay đổi, vì vậy bạn cũng có thể làm cho nó tĩnh. –

1

Trong trường hợp đó, bạn cũng có thể làm cho nó tĩnh. Và quy ước Java là đặt tên các hằng số như vậy trong ALL_CAPS.

1
private static final String name = getName(); 

nơi getName() là một chức năng tĩnh mà được bạn tên.

+0

Hãy coi chừng cấu trúc này nếu getName() thực hiện bất kỳ điều gì khác ngoài trả về hằng số. Bạn có thể tìm thấy logic được sử dụng bởi getName() có thể chưa được khởi tạo. – DJClayworth

3

Đánh dấu nó là tĩnh, sẽ cho phép bạn sử dụng nó trong hàm tạo, nhưng kể từ khi bạn thực hiện nó, nó không thể thay đổi được.

private static final String name = "a_name"; 

cũng có thể sử dụng một khối init tĩnh.

private static final String name; 

static { name = "a_name"; } 

Nếu bạn đang cố gắng sửa đổi giá trị trong hàm tạo, thì bạn không thể gán giá trị mặc định hoặc bạn phải đặt giá trị mặc định.

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

hoặc

private final String name; 

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

Tôi không thể sử dụng nó trong các nhà xây dựng, trong khi java đầu tiên chạy các nhà xây dựng một thì các trường ...

này là không đúng, lĩnh vực được đánh giá đầu tiên, nếu không bạn không thể truy cập bất kỳ giá trị mặc định nào của các thành viên trong các nhà thầu của bạn, vì chúng sẽ không được khởi tạo. này không công việc:

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

Từ khóa thức chỉ đánh dấu sự liên tục thành viên, nó được coi như bất kỳ thành viên khác bằng cách khác.

EDIT: Bạn đang cố gắng đặt giá trị trong hàm tạo không?Điều đó sẽ không hoạt động, vì thành viên là bất biến nếu được định nghĩa là cuối cùng.

+0

Về mặt kỹ thuật, đó là hàm khởi tạo (ngầm) thực hiện logic khởi tạo trường. –

+0

Vâng, ok. Tuy nhiên, các trường được đánh giá đầu tiên. – soulmerge

2

possiblity khác là để khởi tạo lĩnh vực này trong một khối dụ initializer:

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

Chúng tôi đang nhận được ra khỏi câu hỏi.

Có, bạn có thể sử dụng biến số private final. Ví dụ:

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

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

Điều này có nghĩa là lớp Tài khoản có sự phụ thuộc vào hai số, tài khoản và số định tuyến. Các giá trị của các thuộc tính lớp này PHẢI được thiết lập khi lớp Tài khoản được xây dựng và không thể thay đổi số này mà không tạo một lớp mới.

Công cụ sửa đổi 'cuối cùng' ở đây làm cho các thuộc tính không thay đổi.

+2

Về cơ bản, bạn sẽ có được một shot khi đặt các giá trị trong hàm tạo. Sau khi hàm tạo hoàn thành, các thuộc tính là hằng số. –

+2

Tôi gặp lỗi "không thể chỉ định giá trị cho giá trị biến cuối cùng". –

Các vấn đề liên quan