1

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

选项1:

public class MyClass {
    private int myInt = 1;
}

选项 2:

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

5 回答 5

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        
}
于 2014-08-19T08:37:20.203 回答
2

如果是

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

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

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

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

请参阅文档 - 初始化实例成员

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

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

于 2014-08-19T08:35:11.840 回答
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 = 1final int myInt; { myInt = 1; }.

确切的规范可在Java 语言规范 §4.12.4 中找到。最终变量

常量变量是使用常量表达式(第 15.28 节)初始化的原始类型或 String 类型的最终变量。

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

于 2014-08-19T08:54:51.803 回答
1

在第一种情况下,您在声明和初始化成员myInt 在第二种情况下,您在两个语句中执行任务。在这种情况下,添加一对大括号并没有真正的区别。

赋值:丢弃变量的旧值并用新值替换它。喜欢 :

myInt = 8;

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

private int myInt = 1; //both together

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

private int myint;

希望有帮助:)

于 2014-08-19T08:34:37.180 回答
0

没有尊重,但它可以让你的代码更干净。请记住,

{

}

与int无关!

于 2014-08-19T08:33:45.293 回答