2012-06-22 41 views
21
public class Foo { 
    public static void main(String[] args) { 
     float f; 
     System.out.println(f); 
    } 
} 

Tuyên bố in gây ra lỗi biên dịch thời gian sau,Java: Tại sao tôi bắt buộc phải khởi tạo biến cục bộ nguyên thủy?

Biến địa phương f có thể không có được khởi

Nếu nguyên thủy trong Java đã có một default value (float = 0.0f), tại sao tôi lại yêu cầu để xác định một?


Edit:

Vì vậy, hoạt động này

public class Foo { 
    float f; 
    public static void main(String[] args) { 
     System.out.println(new Foo().f); 
    } 
} 

Cảm ơn, tất cả mọi người!

+6

chỉnh sửa: có tác dụng, nhưng việc quảng cáo địa phương thành trường để tránh khởi tạo có thể không phải là ví dụ hợp lý :-) – fvu

+1

@fvu, đó là một ví dụ, vì vậy nó phục vụ một số mục đích. : D – user1329572

Trả lời

41

Vì đó là biến cục bộ. Đây là lý do tại sao không có gì được gán cho nó:

Biến cục bộ hơi khác; trình biên dịch không bao giờ gán giá trị mặc định cho biến cục bộ chưa được khởi tạo. Nếu bạn không thể khởi tạo biến cục bộ của mình ở nơi nó được khai báo, hãy đảm bảo rằng gán cho nó một giá trị trước khi bạn cố gắng sử dụng nó. Việc truy cập biến số địa phương chưa được khởi tạo sẽ dẫn đến lỗi biên dịch.

Chỉnh sửa: Tại sao Java tăng lỗi biên dịch này? Nếu chúng ta nhìn vào các tập tin IdentifierExpression.java lớp, chúng ta sẽ thấy khối này:

... 
if (field.isLocal()) { 
      LocalMember local = (LocalMember)field; 
      if (local.scopeNumber < ctx.frameNumber && !local.isFinal()) { 
       env.error(where, "invalid.uplevel", id); 
      } 
      if (!vset.testVar(local.number)) { 
       env.error(where, "var.not.initialized", id); 
       vset.addVar(local.number); 
      } 
      local.readcount++; 
     } 
... 

Như đã trình bày (if (!vset.testVar(local.number)) {), kiểm tra JDK (với testVar) nếu biến được gán (Vset's source code nơi chúng tôi có thể tìm thấy testVar đang). Nếu không, nó làm tăng các lỗi var.not.initialized từ một properties file:

... 
javac.err.var.not.initialized=\ 
    Variable {0} may not have been initialized. 
... 

Source

+5

Ồ wow, hoàn toàn học được điều gì đó mới mẻ hôm nay! : D – user1329572

+1

Điều này không thực sự * giải thích * "tại sao", phải không? – kryger

+1

@kryger Vui lòng xem bản chỉnh sửa. – Zakaria

5

Trường lớp (không final trường nào) được khởi tạo thành giá trị mặc định. Các biến cục bộ thì không.

Không phải lúc nào cũng cần gán giá trị khi trường được khai báo. Các trường được khai báo nhưng không được khởi tạo sẽ được thiết lập mặc định hợp lý bởi trình biên dịch.

Vì vậy, một lĩnh vực (final phi) như f trong

class C { 
    float f; 
} 

sẽ được khởi tạo 0f nhưng địa phương biến f trong

void myMethod() { 
    float f; 
} 

sẽ không được.

Biến cục bộ được xử lý khác với các trường theo ngôn ngữ. Các biến cục bộ có thời gian tồn tại tốt, vì vậy bất kỳ việc sử dụng nào trước khi khởi tạo có thể là lỗi. Các trường không nên khởi tạo mặc định thường thuận tiện.

+1

+1, Thông tin tuyệt vời về bit không phải 'bít '! : D – user1329572

13

Trong thực tế, trình biên dịch không gán một giá trị mặc định để float f của bạn, bởi vì trong trường hợp này nó là một biến địa phương - và không phải là một lĩnh vực:

biến địa phương là hơi khác nhau; trình biên dịch không bao giờ gán giá trị mặc định cho biến cục bộ chưa được khởi tạo. Nếu bạn không thể khởi tạo biến cục bộ của bạn nơi nó được khai báo, hãy chắc chắn gán nó một giá trị trước khi bạn cố gắng sử dụng nó. Việc truy cập biến cục bộ chưa được khởi tạo sẽ dẫn đến lỗi biên dịch.

2

biến thực tế địa phương được lưu trữ trong stack.Hence có một cơ hội lấy bất kỳ giá trị cũ mặt trong variable.It địa phương là một thách thức lớn đối với lý do bảo mật .. Hiện tại java cho biết bạn phải khởi tạo một biến cục bộ trước khi sử dụng.

1

Giải pháp guys rất đơn giản. các giá trị được lưu trữ trên bộ nhớ heap được khởi tạo bởi kiểu dữ liệu dựa trên trình biên dịch nhưng các biến cục bộ được lưu trữ trên bộ nhớ ngăn xếp để chúng ta phải inialize nó một cách dễ dàng.

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