在 Java 中,运算符对原始类型和原始包装器的执行是否相同 类?

In Java, do operators perform identically on primitive types and primitive wrapper classes?

众所周知,java 中的原语具有数学和逻辑运算符,您可以对其使用。我的问题是相同的操作逻辑是否适用于它们的表兄弟,即原始包装器 class。

Integer a = new Integer(2);
Integer b = new Integer(2);

Integer c = a * b;  //Does c.integerValue() returns 4?
boolean d = a == b; //Is d true? 
Integer e = a | c;  //Does e.integerValue() return 6?
Integer f = c % a;  //Does f.integerValue() return 0?
a++;                //Does a.integerValue() return 3?

所有运算符对原始类型和原始包装器 classes 的执行是否相同?如果不是,那么哪些运算符子集可以同时处理基元及其对象包装器?

不,特别是 ==!= 比较参考文献。

这意味着new Integer(1) != new Integer(1)

其他操作基本相同

等式运算符(==!=)在使用包装器 classes 时不可靠。

首先,他们通常比较对象引用,而不是对象值。例如:

Integer a = new Integer(24);
Integer b = new Integer(24);
System.out.println(a == b); // Prints false
System.out.println(a != b); // Prints true

其次,包装器 class 的创建方式很重要,例如:

Integer a = 24;
Integer b = 24;
System.out.println(a == b); // Prints true
System.out.println(a != b); // Prints false

在这种情况下,当拆箱时,Integer 使用 Integer.valueOf,后者又使用缓存 (IntegerCache) 来存储 -128 到 127 之间的数字。该实现是导致这种奇怪行为的原因。

实际上,IntegerCache class 的实现允许在您 运行 您的程序时通过 属性 java.lang.Integer.IntegerCache.high 配置上限。

这也适用于 Long

经验教训,你最好使用包装器的 equals() 方法。

其余运算符应该可以工作,因为对象中的值在应用运算符之前会自动装箱。

除了上面给出的答案,我想补充以下内容: 对包装类型进行数学运算时要小心。因为你可以获得NullPointerException。考虑这个例子:

    Double a = 5.0;
    Double b = null;

    System.out.println(a + b);