为什么我可以像原语一样测试包装器的不等式?我可以为我创建的 类 做吗?

Why can I test inequality of Wrappers like primitives? Can I do it for classes I create?

在Java中,有包装对象只包含一个基本类型。它们是 Integer, Double, Character, Boolean, Byte, Short, Long, Float,分别装箱 int, double, char, boolean, byte, short, long, float 基本类型。

对于大多数对象,它们无法进行比较,但是您可以实现 ComparableComparator,这样您就可以定义给定类型的一个对象(称之为 Ty)何时是小于、等于或大于同一类型的另一个对象 Ty。但是,如果是这样,您可以使用 compareTo(Ty oth)compare(Ty arg0, Ty arg1) 来测试不等式,两者都 returning int,如果 return 值 < 0,则表示小于,反之亦然相反。

但是,对于数字 Wrapper 对象(包括 Character),您实际上可以使用原语 <, <=, >=, > 的不等关系运算符来比较这些对象,如下面的代码所示:

Integer a = 15;
Integer b = 0;
Double x = 7.5;
Double y = 15.000000000000000000000000001; // Decimal part discarded
Character ch = 'A';

System.out.println(x + " < " + a + " is " + (x < a));
System.out.println(x + " < " + b + " is " + (x < b));
System.out.println(a + " > " + b + " is " + (a > b));

System.out.println(ch + " <= " + 65 + " is " + (ch <= 64)); // 'A' has ASCII code 65
System.out.println(ch + " <= " + 65 + " is " + (ch <= 65));
System.out.println(a + " >= " + b + " is " + (a >= b));

输出

7.5 < 15 is true
7.5 < 0 is false
15 > 0 is true
A <= 65 is false
A <= 65 is true
15 >= 0 is true

请注意,在两个对象之间,==!= 始终有效,分别表示引用相等和不相等。这不是问题的一部分。

这些包装器函数中的 "operator overloading" 个是包装器独有的吗?

首先,一整套复杂的含义已经揭晓。

发生的情况是,对于运算符“>=”、“<=”、“<”和“>”,编译器已经知道它们只能在基本类型上执行,因此自动拆箱发生(将对象类型转换为原始类型)。这就是为什么这些运算符可以在 Integer 实例上执行的原因。

但是,当使用'=='或'!='时,编译器知道它可以直接比较实例,基本上比较两个变量是否引用同一个对象或不。这根本不是真正的整数比较。

事实上,这将 return 错误:

System.out.println("Test == :"+(new Integer(1000) == new Integer(1000)));
System.out.println("Test == :"+(new Integer(100) == new Integer(100)));

这些很可能会 return 错误:

System.out.println("Test == :"+((Integer)1000 == (Integer)1000));
System.out.println("Test == :"+(Integer.valueOf(1000) == Integer.valueOf(1000)));

尽管这些很可能 return 正确:

System.out.println("Test == :"+((Integer)100 == (Integer)100));
System.out.println("Test == :"+(Integer.valueOf(100) == Integer.valueOf(100)));

'Most likely' 因为它要具体实现,甚至可以通过参数控制。

因为在使用 Integer.valueOf(int) 静态工厂方法时,值在 -127..128 范围内的整数对象被保留了。参见 a more elaborate explenation

但请永远不要假设这会永远有效,并始终使用 Comparable 界面,.equals(...),或进行拆箱。

供参考,同时查看这些文章:

  • Why aren't Integers cached in Java?
  • Using == operator in Java to compare wrapper objects