两个类成员声明和初始化之间的区别

时间:2014-08-19 08:29:02

标签: java initialization declaration class-members

以下类成员声明和初始化之间的确切区别是什么?

选项1:

public class MyClass {
    private int myInt = 1;
}

选项2:

public class MyClass {
    private int myInt;
    {
        myInt = 1;
    }
}

5 个答案:

答案 0 :(得分:2)

的情况下
public class MyClass {
    private int myInt;
    {
        myInt = 1;
    }
}

实例初始化块在构造函数每次构造对象之前运行。

在第二种情况下,它是相同的:)

结论:没有区别(但是值得知道在构造对象时会发生什么)。

请参阅docs - Initializing Instance Members

  

Java编译器将初始化程序块复制到每个构造函数中。   因此,这种方法可用于共享一段代码   多个构造函数。

请注意,您可以使用javap -c反编译文件并验证。

答案 1 :(得分:2)

区别在于语法。对于大多数情况,第一种形式更易读并且可以直接使用。第二种形式可以更强大,因为它分离了声明和初始化,但是在这个确切的例子中,编译器将生成完全相同的字节代码。这是因为编译器会将字段初始化器和init块放入每个构造函数中。在更复杂的情况下,您会发现两种方法之间的顺序可能会有所不同;这是一个最好避免的细微区域,因为它可能会导致意外的NullPointerExceptions。

为了说服自己,可以使用javap -c反编译生成的类文件。

我们得到的第一个版本

public class A {
  public A();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_1      
       6: putfield      #2                  // Field myInt:I
       9: return        
}

我们得到的第二个版本

public class B {
  public B();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_1      
       6: putfield      #2                  // Field myInt:I
       9: return        
}

答案 2 :(得分:1)

在第一种情况下,您宣布同意初始化成员myInt 在第二种情况下,您在两个语句中执行任务。在这种情况下,添加一对括号并没有什么不同。

赋值:丢弃变量的旧值并将其替换为新值。喜欢:

myInt = 8;

初始化:这是一种特殊的任务:第一种。在初始化对象具有空值之前,基本类型具有默认值,例如0或false。(可以与声明一起完成,如第一种情况中所做的那样),如:

private int myInt = 1; //both together

声明:声明声明变量的类型及其名称。变量只能声明一次。编译器使用它来帮助程序员避免错误,例如将字符串值分配给整数变量。在读取或分配变量之前,必须声明该变量。喜欢:

private int myint;

希望有所帮助:)

答案 3 :(得分:1)

如果变量被声明为final,那将会有所不同。如果在声明时使用编译时常量立即分配final变量,则该变量也将是编译时常量。这意味着,它的值将在编译时复制,而不是在访问变量时在运行时读取,并且它可能出现在只允许编译时常量的位置:

仅供参考:

public class MyClass {
  private final int myInt = 1;
  private final int myIntPlusOne = myInt + 1;// adding two constants

  public MyClass(int parameter) {
    switch(parameter)
    {
      case myInt: // using a name for 1
      case myIntPlusOne: // and for 2
    }
  }
}

如果您将final int myInt = 1更改为final int myInt; { myInt = 1; },则无效。

确切的规范可在Java Language Specification §4.12.4. final Variables

中找到
  

常量变量是基本类型或类型String的最终变量,使用常量表达式(§15.28)进行初始化。

对于非final变量,它没有任何区别。

答案 4 :(得分:0)

没有任何尊重,但它可以让您的代码更清晰。 请记住

{

}

与int无关!