我总是理解静态变量在引用时共享一个实例。我想对此进行测试,但结果与我预期的不同。
static Integer counter = 0;
static Integer test = counter;
public static void main(String args[]) {
counter++;
System.out.println("counter: " + counter);
System.out.println("test: " + test);
}
输出:
计数器:1
测试:0
由于test
引用counter
我认为当我增加counter
时,test
也将自动增加。但是,似乎test
从某个地方引用0
,问题是,在哪里?
答案 0 :(得分:4)
由于
test
引用counter
这种假设是错误的。在Java中,您不能引用变量。存储在变量中的是一个值。该值可以是基本类型值或引用类型值。在基元的情况下,该值是基元的值。在参考类型的情况下,
在
int a = 0;
int b = a;
评估变量a
以生成值0
,该值存储在b
中。
在
Integer a = 0;
Integer b = a;
0
转换为Integer
到Integer.valueOf(int)
,值Integer
对象的引用存储在a
中。然后评估a
,生成对Integer
对象的引用值,该值存储在b
中。
这与
中讨论的概念相同此外,变量static
这一事实无关紧要。
解决这个问题的唯一方法是手动更新test
,
counter++;
test = counter;
答案 1 :(得分:2)
这是我的理解。
Integer counter = 0;
您实际在做的是什么时
Integer counter = new Integer(0);
在这里,您创建了一个Integer object
,其值为0,counter
正在为此提供帮助。 第2步: Integer test = counter;
现在test
也指同一个Integer object
我们
在步骤1中创建。
第3步:这是棘手的部分。在主方法中执行counter++;
时,Java 自动装箱和自动装箱
功能正在为您实现以下代码。
counter = Integer.valueOf(counter.intValue() + 1);
由于Integer
类在Java中是不可变的,当值从0递增到1时,valueOf()
方法正在创建一个新的Integer object
并存储其中的新值为1而不是更改旧对象的值(请参阅下面的Java的 valueOf()方法实现)。当您使用counter
引用新对象时,它会取消引用其值为0的旧Integer object
。但引用变量test
仍然保留旧的Integer object
。这是test
打印旧值的原因。
来自库类Integer的Java的valueOf()方法
638 public static Integer More ...valueOf(int i) {
639 assert IntegerCache.high >= 127;
640 if (i >= IntegerCache.low && i <= IntegerCache.high)
641 return IntegerCache.cache[i + (-IntegerCache.low)];
642 return new Integer(i); //See, new object is created here.
643 }
请参阅下文,了解详细的图解说明。
实线表示参考变量仍然保持对象。
虚线表示引用变量不再持有对象。
答案 2 :(得分:1)
test
没有引用counter
。它具有相同的初始值。 int
是原始的。
答案 3 :(得分:0)
test
不是指向counter
的指针:您将其值设置为最初等于计数器,但counter
的任何后续更改都不会反映在test
的值中{1}}。
如果你想对同一个可变值有两个引用,你可以使用像AtomicInteger
这样的东西:
static AtomicInteger counter = new AtomicInteger(0);
static AtomicInteger test = counter;
public static void main(String args[]) {
counter.incrementAndGet();
System.out.println("counter: " + counter);
System.out.println("test: " + test);
}
输出:
counter: 1
test: 1
答案 4 :(得分:-2)
您需要区分基元和引用对象。整数不是原始的'per-se',但由于'boxing',它们具有特殊属性。你拥有的是intValue()的原语,因此它获得了初始值(它与计数器没有更多关系)。
嗯......对于记录'降级':OP已将他的字段从'int'更改为'Integers',因此我的初始答案不正确。