默认变量的值与初始化的默认值 [英] Default variables' values vs initialization with default

查看:218
本文介绍了默认变量的值与初始化的默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们都知道,根据 JLS7 p .4.12.5 每个实例变量都使用默认值进行初始化。例如。 (1):

We all know, that according to JLS7 p.4.12.5 every instance variable is initialized with default value. E.g. (1):

public class Test {
    private Integer a;  // == null
    private int b;      // == 0
    private boolean c;  // == false
}

但我一直认为,这样的类实现(2 ):

But I always thought, that such class implementation (2):

public class Test {
    private Integer a = null;
    private int b = 0;
    private boolean c = false;
}

绝对等于示例(1)。我预计,复杂的Java编译器会发现(2)中的所有这些初始化值都是多余的并且省略了它们。

is absolutely equal to example (1). I expected, that sophisticated Java compiler see that all these initialization values in (2) are redundant and omits them.

但是对于这两个类我们突然有两个不同的字节 - 码。

But suddenly for this two classes we have two different byte-code.

例如(1):

   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

例如(2):

   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   aconst_null
   6:   putfield    #2; //Field a:Ljava/lang/Integer;
   9:   aload_0
   10:  iconst_0
   11:  putfield    #3; //Field b:I
   14:  aload_0
   15:  iconst_0
   16:  putfield    #4; //Field c:Z
   19:  return

问题是:为什么?但这是显而易见的优化事项。是什么原因?

The question is: Why? But this is so obvious thing to be optimized. What's the reason?

UPD:我使用Java 7 1.7.0.11 x64,没有特殊的javac选项

UPD: I use Java 7 1.7.0.11 x64, no special javac options

推荐答案

不,它们不等同。在对象实例化时,默认值立即。当调用超类构造函数时,字段初始值设定项中的赋值发生...这意味着可以在某些情况下看到差异。示例代码:

No, they're not equivalent. Default values are assigned immediately, on object instantiation. The assignment in field initializers happens when the superclass constructor has been called... which means you can see a difference in some cases. Sample code:

class Superclass {
    public Superclass() {
        someMethod();
    }

    void someMethod() {}
}

class Subclass extends Superclass {
    private int explicit = 0;
    private int implicit;

    public Subclass() {
        System.out.println("explicit: " + explicit);
        System.out.println("implicit: " + implicit);
    }

    @Override void someMethod() {
        explicit = 5;
        implicit = 5;
    }
}

public class Test {
    public static void main(String[] args) {
        new Subclass();
    }
}

输出:

explicit: 0
implicit: 5

在这里你可以看到显式字段初始化重置显式的值在超类构造函数已完成但在子类构造函数 body 执行之前。 隐式的值仍然具有在超类的 someMethod 的多态调用中指定的值构造函数。

Here you can see that the explicit field initialization "reset" the value of explicit back to 0 after the Superclass constructor finished but before the subclass constructor body executed. The value of implicit still has the value assigned within the polymorphic call to someMethod from the Superclass constructor.

这篇关于默认变量的值与初始化的默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆