Java 如何使用整数溢出违反可比接口第一规定?

Java 如何使用整数溢出违反可比接口第一规定?,java,comparable,effective-java,Java,Comparable,Effective Java,java.lang.Comparable#compareTo方法声明为第一条规定 实现者必须确保sgn(x.compareTo(y))=-sgn(y.compare- 对于所有的x和y。(这意味着x.compareTo(y)必须抛出 异常当且仅当y.compareTo(x)引发异常时。) 根据Joshua Bloch在第12项中的有效Java 这个技巧在这里很管用,但使用时要格外小心。 除非您确定有问题的字段是正确的,否则不要使用它 非负的,或者更一般地说,即 可能的最低和最高字段值小于或等于

java.lang.Comparable#compareTo
方法声明为第一条规定

实现者必须确保sgn(x.compareTo(y))=-sgn(y.compare- 对于所有的x和y。(这意味着x.compareTo(y)必须抛出 异常当且仅当y.compareTo(x)引发异常时。)

根据Joshua Bloch在第12项中的有效Java

这个技巧在这里很管用,但使用时要格外小心。 除非您确定有问题的字段是正确的,否则不要使用它 非负的,或者更一般地说,即 可能的最低和最高字段值小于或等于 整数。最大值(231-1)。这个把戏不总是奏效的原因 有符号32位整数的大小不足以容纳 两个任意有符号32位整数之间的差。如果我是一个 大的正整数,j是大的负整数,(i-j)将 溢出并返回负值。结果比较法 将为某些参数返回不正确的结果,并违反第一个参数 第二条与合同条款相比较。这不是一个纯粹的问题 理论问题:它导致了实际系统的故障。这些 故障可能很难调试,因为断开的compareTo方法 适用于大多数输入值

对于整数溢出,您可以违反第一条规定,但我找不到如何违反,此示例显示了如何违反第一条规定:

public class ProblemsWithLargeIntegers implements Comparable<ProblemsWithLargeIntegers> {

    private int zas;

    @Override
    public int compareTo(ProblemsWithLargeIntegers o) {
        return zas - o.zas;
    }

    public ProblemsWithLargeIntegers(int zas) {
        this.zas = zas;
    }

    public static void main(String[] args) {
      int value1 = ...;
      int value2 = ...;
      ProblemsWithLargeIntegers d = new ProblemsWithLargeIntegers(value1);
      ProblemsWithLargeIntegers e = new ProblemsWithLargeIntegers(value2);
      if (!(Math.signum(d.compareTo(e)) == -Math.signum(e.compareTo(d)))){
        System.out.println("hey!");
    }

}
公共类问题大整数实现可比较{
私人国际旅行社;
@凌驾
公共整数比较(问题是大整数o){
返回zas-o.zas;
}
公共问题大整数(int-zas){
this.zas=zas;
}
公共静态void main(字符串[]args){
int值1=。。。;
int值2=。。。;
ProblemsWithLargeIntegers d=新问题sWithlargeIntegers(值1);
ProblemsWithLargeIntegers e=新问题sWithlargeIntegers(值2);
if(!(Math.signum(d.compareTo(e))==-Math.signum(e.compareTo(d))){
System.out.println(“嘿!”);
}
}

所以我想要一个
value1
和一个
value2
来得到它?有什么想法吗?或者Joshua错了?

好吧,这违反了一般合同。例如,以
value1=Integer.MIN\u VALUE
value2=1
为例。这将有效地报告
Integer.MIN\u VALUE>1

编辑:事实上,我错了——很容易违反第一条规定:

int value1 = Integer.MIN_VALUE;
int value2 = 0;

两次比较都会得到一个否定的结果,因为
Integer.MIN\u VALUE-0
=
0-Integer.MIN\u VALUE

好吧,这从一开始就违反了一般约定。例如,取
value1=Integer.MIN\u VALUE
value2=1
。这将报告
Integer.MIN\u VALUE>1
,效果我很高兴

编辑:事实上,我错了——很容易违反第一条规定:

int value1 = Integer.MIN_VALUE;
int value2 = 0;

两次比较都会得到一个否定的结果,因为
Integer.MIN\u VALUE-0
=
0-Integer.MIN\u VALUE

是的,这是真的,但不是第一条规定,这不是我想要得到的答案,这是对的……但是在测试了您提供的值之后,我发现
Integer.MIN\u VALUE==-Integer.MIN\u VALUE
是真的吗
…现在我confused@Jaime:是的,没错。查看支持的值的确切范围,然后考虑它可能会给出什么其他结果…是的,这是真的,但不是第一个规定,这不是我试图得到的。没错…但在测试您提供的值后,我发现
Integer.MIN\u值==-Integer.MIN_值
…现在我confused@Jaime:是的,没错。请查看支持的值的确切范围,然后思考它可以给出什么其他结果。。。