Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 默认变量';默认值与初始化_Java_Bytecode_Compiler Optimization - Fatal编程技术网

Java 默认变量';默认值与初始化

Java 默认变量';默认值与初始化,java,bytecode,compiler-optimization,Java,Bytecode,Compiler Optimization,我们都知道,根据每个实例,变量都是用默认值初始化的。例如:(1): 但我一直认为,这样的类实现(2): 与示例(1)完全相同。我预计,复杂的Java编译器会发现(2)中的所有这些初始化值都是冗余的,并且会忽略它们 但是突然,对于这两个类,我们有了两个不同的字节码 例如(1): 0:aload\u 0 1:特别是#1//方法java/lang/Object。“:()V 4:返回 例如(2): 0:aload\u 0 1:特别是#1//方法java/lang/Object。“:()V 4:aloa

我们都知道,根据每个实例,变量都是用默认值初始化的。例如:(1):

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

与示例(1)完全相同。我预计,复杂的Java编译器会发现(2)中的所有这些初始化值都是冗余的,并且会忽略它们

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

例如(1):

0:aload\u 0
1:特别是#1//方法java/lang/Object。“:()V
4:返回
例如(2):

0:aload\u 0
1:特别是#1//方法java/lang/Object。“:()V
4:aload_0
5:aconst_null
6:putfield#2//字段a:Ljava/lang/Integer;
9:aload_0
10:iconst_0
11:putfield#3//b场:我
14:aload_0
15:iconst_0
16:putfield#4//字段c:Z
19:返回
问题是:为什么?但这显然是一件需要优化的事情。原因是什么


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

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

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

在这里,您可以看到显式字段初始化在
超类
构造函数完成后但在子类构造函数体执行之前将
显式
的值“重置”回0。
隐式
的值仍然具有从
超类
构造函数对
someMethod
的多态调用中指定的值。

如果使用(如果我记得正确的话)
-O
启用优化,结果是否相同?它是
-O
(大写),虽然只是测试过,但它并没有被优化。@JoachimIsaksson:当你在真实代码中被它咬到的时候,很容易记住;)对在这种情况下,编译器应该能够优化,因为没有基类要考虑。还是我遗漏了什么?@JoachimIsaksson:我认为
javac
执行这种优化是错误的。我认为,字节码最好能紧密地表示源代码。JIT编译器可能会对其进行优化。这也适用于C#吗?@Joachim,即使这是有效的,Java编译器几乎从不优化任何东西。这就是反编译如此容易的原因。
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
   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
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