[英]Why is unitialized object in Java not set to null?
我在這里遇到一個非常基本的問題,即使它必須存在,我也無法找到解決方案。
我有以下代碼:
public class Foo {
public static void main(String[] args) {
String foo;
if (foo != null) {
System.out.println("foo");
} else {
System.out.println("foo2");
}
}
}
它給了我
''變量可能尚未初始化''
。 為什么我必須明確地指定null,並且默認情況下並非所有變量都用null初始化?
它可以防止您在明確分配之前意外使用局部變量。 這是一件好事 -它有助於防止錯誤。 遺憾的是它不能用於字段(實例和靜態變量) - 但除了最終變量之外,編譯器不知道你什么時候讀取它們與你要分配它們的時間 - 它無法告訴您要調用方法的順序。 在單個方法中,它有更多關於流量控制的信息,因此可以為您提供更多檢查。
如果您希望局部變量的值為null,為什么不將它顯式設置為null? 這不僅讓編譯器感到高興 - 它也清楚地說明了你的意圖。
有關明確賦值的更多詳細信息,請參見Java語言規范的第16章 。
這是一個如何防止錯誤的例子:
Iterable<String> collectionOfNames = ...; // Some method call
String lastNameInCollection;
for (String name : collectionOfNames)
{
lastNameInCollection = name;
}
System.out.println("The last name was: " + lastNameInCollection);
如果收集是空的,會發生什么? 也許我們想打印“姓氏是:null” - 但也許我們應該做點其他事情。 以上不能編譯的事實(因為可能沒有分配lastNameIncollection
)迫使程序員考慮名稱集合為空的情況。
保留未初始化變量有時是一件好事,允許編譯器在使用它之前檢查它是否已在代碼的所有可能分支中分配。 例如,如果您具有指定變量的復雜條件,則永遠不應為null
:
String variable;
if (conditionA) {
if (conditionB)
variable = "B";
else
variable = "A";
} else {
switch (conditionC) {
case 1:
variable = "C1";
break;
case 2:
variable = "C2";
break;
default:
variable = "CD";
break;
}
}
System.out.println(variable.length());
如果您忘記在其中一個分支中分配變量,編譯器將會抱怨。 既然你知道,你永遠不會分配null
,你可以安全地使用變量而不檢查它是否為null
。 如果在定義中使用null
初始化變量,並且忘記將變量設置為值,則編譯器將無法檢查此值,並且您可以獲得NullPointerException
:
String variable = null;
if (conditionA)
variable = "A";
// NullPointerException if conditionA is false, not check by compiler
System.out.println(variable.length());
變量也可以是final,在這種情況下,它只能分配一次。 如果您使用默認值對其進行初始化,則它已經被分配並且無法重新分配:
final int variable;
if (condition)
variable = 1;
else
variable = 2;
簡單的答案是:
成員局部變量不會使用'null'值自動初始化。 但類成員變量是。
這段代碼可行
public class Foo {
String foo;
public static void main(String[] args) {
if (foo != null) {
System.out.println("foo");
} else {
System.out.println("foo2");
}
}
}
或者這個
public class Foo {
public static void main(String[] args) {
String foo = null;
if (foo != null) {
System.out.println("foo");
} else {
System.out.println("foo2");
}
}
}
如果您想完全深入了解這個主題,請考慮Jon Skeet的回答並檢查他提供的鏈接。
初始化它也是完全沒必要的,如果它稍后被初始化:
String foo;
if (specialUseCase) {
foo = "this";
} else {
foo = "that";
}
由於局部變量未自動初始化,因此必須顯式初始化它們。即使未顯式初始化,也只能將成員變量初始化為null或默認值。 如果你保留String foo;
在方法main()之外,您不需要初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.