【问题标题】:Java variable and constructor initialization? [duplicate]Java变量和构造函数初始化? [复制]
【发布时间】:2017-01-18 13:44:33
【问题描述】:

给定下面的代码:

public class A {

   private int i = 6;
   private int j = i;

   public A() {
       i = 5;
   }

   public static void main(String[] args) {
      A a = new A();
      System.out.println(a.i + a.j);
   }
}

为什么这个加法的输出是 11 而不是 10?据我了解,构造函数在静态变量和实例变量初始化后最后运行。因此,如果构造函数是最后一个被触发的,它应该将 i 和 j 都设置为 5,因为它们指向相同的数字。有人可以逐步解释这里发生的事情,以便执行后值为 11。任何反馈将不胜感激。

【问题讨论】:

    标签: java variables constructor initialization


    【解决方案1】:

    因为它们指向同一个数字

    Java 中没有指针。

    ij 是保存整数值的原始变量。

    int j = i;
    

    j 的当前值分配给i。分配后更改i 不会更改j

    因此i先初始化为6,然后j赋值为6,再将i改为5(不会改变j的值)。

    【讨论】:

    • 所以输出为 11 的原因是因为这些是原语而不是对象?如果它们是对象,那么引用肯定会在内存中寻址同一个对象,并且对象 j 将与 i 相同((j == i) 为真)。
    • @CBA110 否。如果您使用Integer 而不是int,答案将是相同的。当您为变量分配新值(无论是原始值还是对对象的引用)时,您不会影响在分配之前碰巧具有相同值的其他变量的值。另一方面,如果ij 都引用同一个可变对象,那么调用i.setSomething(value) 也会改变j 引用的对象的状态,因为两者都引用同一个对象。
    • 完美。谢谢@Eran。
    【解决方案2】:

    您所描述的内容适用于 reactive programming 模型。 JVM 不是这样工作的。 j 变量包含 i 在字段声明中赋值时的旧值。因此它的值仍然是6i的值改变后,新的值不会发布到j

    【讨论】:

      【解决方案3】:

      Java 中的一切都是指针,它只是对你隐藏它。当您来自其他语言时,这可能会导致混淆。

      private int i = 6; // i is an int pointer, the value hold at his address is 6
      private int j = i; // j is an int pointer, its value is assigned from the value hold at i, therefore it is 6
      A a = new A(); // i is now assigned a value of 5, but i and j have different address, so j isn't impacted.
      

      如果你想要你描述的这种行为,你必须使用一个对象。

      private int[] i = new int[] {6}; // Not sure of this syntax
      private int[] j = i;
      i[0] = 5;
      System.out.println(i[0]+j[0]);
      

      就是这样。

      【讨论】:

        【解决方案4】:

        执行流程是:-

        private int i = 6;
        private int j = i;
        

        这两条语句首先执行,所以ij的值为6。 现在,当您调用构造函数时,您会得到 i=5i 的值现在已更改,但 j 的值仍为 6。

        所以当您说a.i+a.j 时,它是 5+6,因此 11 就是答案。 i 中的更改不会更改 j,因为它们是原始数据类型和对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-23
          • 1970-01-01
          • 1970-01-01
          • 2018-01-08
          • 2020-09-27
          • 2015-02-19
          相关资源
          最近更新 更多