变量可能没有初始化错误

时间:2010-03-15 16:45:29

标签: java variables initialization

当我尝试编译时:

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

在我看来,我在方法的顶部初始化它们。什么出错了?

12 个答案:

答案 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 节(明确分配))。

因此,由于变量 ab 未初始化:

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

    ...   
}

所以即使上面的代码可以被正式证明是有效的(变量ab将始终被赋值为{{1} } 和0)尝试分析应用程序的逻辑不是编译器的工作局部变量初始化的规则也不是 依靠它。编译器检查变量 1a 是否根据局部变量初始化规则被初始化,并相应地反应例如, 显示编译错误)。

答案 5 :(得分:2)

您声明了它们,但未使用值初始化它们。添加如下内容:

int a = 0;

答案 6 :(得分:1)

您尚未初始化ab,只是声明了它们。有一个微妙的区别。

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;