当我尝试编译时:
public static Rand searchCount (int[] x)
{
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
...
}
我收到这些错误:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
2 errors
在我看来,我在方法的顶部初始化它们。什么出错了?
答案 0 :(得分:78)
你宣布他们,但你没有初始化它们。初始化它们将它们设置为等于值:
int a; // This is a declaration
a = 0; // This is an initialization
int b = 1; // This is a declaration and initialization
您收到错误是因为您尚未初始化变量,但是您在a++
循环中递增了它们(例如,for
)。
Java基元具有默认值,但是作为一个用户在下面评论
声明为类成员时,它们的默认值为零。局部变量没有默认值
答案 1 :(得分:73)
局部变量不会获得默认值。它们的初始值是未定义的,没有通过某种方式分配值。在使用局部变量之前,必须初始化它们。
当您在类级别(作为成员,即作为字段)和方法级别声明变量时,会有很大的不同。
如果在类级别声明字段,则会根据其类型获取默认值。如果在方法级别或作为块声明变量(意味着{}中的任何代码),则不会获取任何值并保持未定义,直到他们获得一些起始值,即分配给它们的某些值。
答案 2 :(得分:6)
如果它们被声明为类的字段,那么它们将真正用0初始化。
你有点困惑,因为如果你写:
class Clazz {
int a;
int b;
Clazz () {
super ();
b = 0;
}
public void printA () {
sout (a + b);
}
public static void main (String[] args) {
new Clazz ().printA ();
}
}
然后此代码将打印“0”。这是因为在创建Clazz的新实例时将调用一个特殊的构造函数。首先调用super ()
,然后隐式初始化字段a
,然后执行第b = 0
行。
答案 3 :(得分:3)
你声明了它们,但没有初始化。
int a; // declaration, unknown value
a = 0; // initialization
int a = 0; // declaration with initialization
答案 4 :(得分:3)
由于没有其他答案引用Java语言标准,我决定自己写一个答案:
在 Java 中,默认情况下,局部变量不会使用某个值进行初始化(例如,与类的字段不同)。从语言规范一 (§4.12.5) 可以阅读以下内容:
<块引用>局部变量(第 14.4 节、第 14.14 节)必须明确指定一个值 在使用之前,通过初始化(第 14.4 节)或赋值 (第 15.26 节),以一种可以使用确定规则进行验证的方式 分配(第 16 节(明确分配))。
因此,由于变量 a
和 b
未初始化:
for (int l= 0; l<x.length; l++)
{
if (x[l] == 0)
a++ ;
else if (x[l] == 1)
b++ ;
}
无论如何,操作 a++;
和 b++;
无法产生任何有意义的结果。所以编译器通知你它是合乎逻辑的:
Rand.java:72: variable a might not have been initialized
a++ ;
^
Rand.java:74: variable b might not have been initialized
b++ ;
^
但是,需要理解的是,a++;
和 b++;
无法产生任何有意义的结果这一事实与编译器显示错误的原因无关。而是因为它在 Java 语言规范中明确设置
局部变量(第 14.4 节、第 14.14 节)必须显式地赋予一个值 (...)
为了展示上述观点,让我们将您的代码更改为:
public static Rand searchCount (int[] x)
{
if(x == null || x.length == 0)
return null;
int a ;
int b ;
...
for (int l= 0; l<x.length; l++)
{
if(l == 0)
a = l;
if(l == 1)
b = l;
}
...
}
所以即使上面的代码可以被正式证明是有效的(即变量a
和b
将始终被赋值为{{1} } 和0
)尝试分析应用程序的逻辑不是编译器的工作,局部变量初始化的规则也不是 依靠它。编译器检查变量 1
和 a
是否根据局部变量初始化规则被初始化,并相应地反应(例如, 显示编译错误)。
答案 5 :(得分:2)
您声明了它们,但未使用值初始化它们。添加如下内容:
int a = 0;
答案 6 :(得分:1)
您尚未初始化a
和b
,只是声明了它们。有一个微妙的区别。
int a = 0;
int b = 0;
至少这是针对C ++的,我认为Java是相同的概念。
答案 7 :(得分:1)
您在方法的开头声明了它们,但您从未初始化它们。初始化将它们设置为等于值,例如:
int a = 0;
int b = 0;
答案 8 :(得分:1)
你声明了它们但没有为它们提供初始值 - 因此,它们是未初始化的。尝试类似:
public static Rand searchCount (int[] x)
{
int a = 0 ;
int b = 0 ;
并且警告应该消失。
答案 9 :(得分:1)
想象一下,如果x [l]在循环中既不是0也不是1会发生什么。在这种情况下,a和b永远不会被分配给并具有未定义的值。 您必须使用某个值初始化它们,例如0。
答案 10 :(得分:1)
将变量“a”设置为某个值,如下所示,
a=0;
声明和初始化都是不同的。
祝你好运
答案 11 :(得分:1)
在使用之前初始化方法块内的局部变量是一种很好的做法。这是一个初学者可能犯的错误。
public static void main(String[] args){
int a;
int[] arr = {1,2,3,4,5};
for(int i=0; i<arr.length; i++){
a = arr[i];
}
System.out.println(a);
}
您可能希望控制台显示“5”,但编译器会抛出“变量a可能未初始化”错误。虽然有人可能认为变量a在for循环中被“初始化”,但编译器并没有这么想。如果arr.length
为0,该怎么办? for循环根本不会运行。因此,编译器会给variable a might not have been initialized
指出潜在的危险,并要求您初始化变量。
要防止出现此类错误,请在声明时初始化该变量。
int a = 0;