2012-07-05 4 views
10

Tôi đã xem xét một số khác question về biến cuối cùng và nhận thấy rằng bạn có thể khai báo biến cuối cùng mà không khởi tạo chúng (biến số blank final). Có một lý do nào đó là mong muốn để làm điều này, và khi nào nó có lợi thế?Khi nào thích hợp để sử dụng các biến số trống cuối cùng?

+1

khá nhiều không bao giờ. trận chung kết trống không làm gì cả. chúng là những biến không bao giờ có giá trị ý nghĩa nào. bất kỳ trình biên dịch java có giá trị muối của nó sẽ cung cấp cho bạn một cảnh báo và/hoặc lỗi. –

+1

Điều này có thể hữu ích khi bạn muốn khởi tạo nó trong hàm tạo (dựa trên một số tham số hàm tạo). – sshannin

+0

Cuối cùng là cuối cùng .. nếu bạn cố gắng làm cuối cùng int a = 2; a = 3; nó sẽ ném một lỗi –

Trả lời

25

này rất hữu ích để tạo các đối tượng bất biến:

public class Bla { 
    private final Color color; 

    public Bla(Color c) {this.color = c}; 

} 

Bla là không thay đổi (một lần tạo ra, nó không thể thay đổi vì màu sắc là cuối cùng). Nhưng bạn vẫn có thể tạo ra nhiều Blas khác nhau bằng cách xây dựng chúng với nhiều màu sắc khác nhau.

Xem thêm this question chẳng hạn.

EDIT

Có lẽ đáng nói thêm rằng một "trống cuối cùng" có một ý nghĩa rất đặc biệt trong Java, mà dường như đã tạo ra một số nhầm lẫn trong các ý kiến ​​- cf Java Language Specification 4.12.4:

Một trống cuối cùng là một biến cuối cùng có khai báo thiếu một initializer.

Sau đó, bạn phải gán biến trống cuối cùng đó trong một hàm tạo.

+2

Ở đó tôi đã nghĩ tôi đã đúng khi nói bạn không thể làm điều này. :) Tôi không biết điều này. +1 –

+0

Ngắn gọn và rõ ràng. Cảm ơn! –

2

Bạn có thể làm điều này khi bạn không biết giá trị sẽ là gì trước khi thiết bị của một đối tượng, nó chỉ cần có một giá trị được gán trong hàm tạo của nó.

Đây là cách bạn tạo immutable objects và được sử dụng trong mẫu trình tạo.

class Builder{ 
    final BuilderContext context; 

    private Builder(BuilderContext context){ 
     this.context=context; 
    }  

    public static Builder New(){ 
     return new Builder(new BuilderContext()); 
    } 
+1

Trình biên dịch _will_ phàn nàn về 'new' làm tên phương thức. –

+0

right sorry Ill chuyển sang New, tôi đã nhập nhanh chóng –

+0

Không nên phương thức New() được khai báo tĩnh? @JohnKane – piepi

0

nhận thấy rằng bạn có thể khai báo final biến mà không cần khởi tạo chúng

Bạn phải khởi tạo nó sau này (ví dụ như trong các nhà xây dựng) nên nó sẽ không ở lại trống rỗng.

4

Thuộc tính cuối cùng của lớp phải có giá trị được gán trước khi đối tượng được tạo. Vì vậy, điểm cuối cùng mà bạn có thể gán giá trị cho chúng là constructor.

Điều này được sử dụng thường xuyên cho immutable objects.

public class Foo { 

    private final Bar bar; 

    public Foo(Bar bar) { 
    this.bar = bar; 
    } 

    public Bar getBar() { 
    return new Bar(bar); 
} 
} 

What wiki says about it

Defensive copying.

+0

Đúng. Đây là những gì một "trống cuối cùng" đề cập đến, theo trích dẫn Wikipedia. –

+0

@LouisWasserman, tôi đã không nhận ra rằng wiki mô tả nó. Tôi đã thêm một ref vào Wiki nhưng, "của bạn trống cuối cùng" cho thấy rằng Wiki không phải là nơi tốt nhất để đạt được kiến ​​thức. ;-). –

+0

Đợi đã, cái gì? Câu trả lời được chấp nhận cho câu hỏi mà OP được liên kết bao gồm một liên kết Wikipedia, có một trích dẫn đồng ý với câu trả lời của bạn. –

0

Từ Wikipedia

Các thức trống, được giới thiệu trong Java 1.1, là một biến thức có khai thiếu một initializer. Một trống cuối cùng chỉ có thể được gán một lần và phải được bỏ gán khi một nhiệm vụ xảy ra. Để làm điều này, một trình biên dịch Java chạy một phân tích lưu lượng để đảm bảo rằng, đối với mỗi phép gán cho một biến cuối cùng trống, biến chắc chắn chưa được gán trước khi gán; nếu không xảy ra lỗi biên dịch.Nói chung, một trình biên dịch Java sẽ đảm bảo rằng cuối cùng trống không được sử dụng cho đến khi nó được gán một giá trị và một khi được gán một giá trị, biến cuối cùng bây giờ không thể được gán lại một giá trị khác.

1

Biến cuối cùng trống phải được gán "một nơi nào đó" trong hàm tạo. Một ví dụ thay vì xây dựng:

public class Test { 
    final int sign; 
    public Test(String upDown) { 
     if (upDown.equals("up")) { 
      sign = +1; 
     } else { 
      sign = -1; 
     } 
    } 
} 
1

Một trường hợp có thể là khi bạn có một lĩnh vực mà bạn muốn tuyên bố chính thức, nhưng có nhiệm vụ có thể ném một ngoại lệ và bạn muốn để có thể hành động nếu điều đó xảy ra:

class A { 
    final URLConnection conn; 
    A(String url) { 
    try { 
     this.conn = new URL(url).openConnection(); 
    } catch (IOException | MalformedURLException e) { 
     // Maybe this isn't fatal, so just handle the Exception 
     // here and move on happily 
    } 
    } 
} 
1

Sử dụng biến trống cuối cùng bên trong một phương thức để cho thấy rằng tất cả các đường dẫn mã sử dụng biến gán biến đó chính xác một lần (hoặc ném ngoại lệ). Trình biên dịch Java sẽ đảm bảo rằng một biến cuối cùng trống được gán trước khi nó được sử dụng.

Ví dụ mã bên trong một số phương pháp:

final Foo foo; 
    if (condition1()) { 
    foo = makeFoo(1); 
    } else if (condition2()) { 
    throw new BarException(); 
    } else { 
    foo = makeFoo(-1); 
    } 
    ... 
    blahBlahBlah(foo); 

Sử dụng các biến thức trống cho người đọc tiếp theo của mã mà người nhận bảo lãnh trình biên dịch rằng ai đó gán foo trước khi gọi blahblahblah (foo).

Câu hỏi hỏi về "biến số trống cuối cùng". Thảo luận về "các trường trống cuối cùng " là một cuộc thảo luận khác và thú vị theo đúng nghĩa của nó.