一、问题
在基本类型int中,根据面向对象的思维,它有对应的Integer包装类型,里面定义了操作该基本类型的属性和方法。当使用“==”去比较两个int类型的数时,在开发环境下比较的结果是正确的,但在实际生成环境下,比较的结果是错误的。
二、原因
在JVM中,根据享元模式的设计结构,Java运行时系统对Integer对象的缓存是通过一个叫做IntegerCache的内部类来实现的。IntegerCache是在Integer类中的私有静态内部类,它缓存了一个范围内的Integer对象,这个范围可以通过参数进行配置。在Java 8中,默认情况下,IntegerCache缓存了-128到127之间的Integer对象。这意味着在这个范围内创建的Integer对象可以被重用,而不需要重新创建新的对象。所以如果参与比较的两个数刚好落在这个范围(如 2 和 2 比较),使用==返回是true,如果是128 与128用==比较,则结果为false。而实际生产环境的数值远远大于这个一级缓存范围,所以即时两个数相同使用==也会出现错误。
IntegerCache只是对于自动装箱(Autoboxing)操作有效。当我们使用直接赋值的方式创建Integer对象时,并不会利用IntegerCache。例如,通过Integer i = 200;创建的Integer对象并不会使用IntegerCache中的缓存。但是,当使用Integer.valueOf()方法创建Integer对象时且只有当数值落在这个范围内时才会直接返回缓存中的对象。
三、解决方法
使用包装类中的比较方法equlas()或compareTo()