java的数值比较和拆箱、封箱

版权声明:转载请注明来源 https://blog.csdn.net/tangyuan_sibal/article/details/86566687

java数值比较

什么是拆箱和装箱

本来在java SE5以前如果要生成一个数值为10的Integer对象,必须这样进行
Integer i = new Integer(10);
但提供了自动装箱技术之后就不用了,只需要这样:
Integer i = 10;
这个过程中会自动根据数值创建对应的 Integer对象,这就是装箱。
那什么是拆箱呢?顾名思义,跟装箱对应,就是自动将包装器类型转换为基本数据类型:
Integer i = 10; //装箱
int n = i; //拆箱

1、“==”

(1)Integer跟Integer之间的比较:

①如果是在-127~128之间,他们会拿到SMALL_VALUES数组里面的同一个对象,他们引用
到了同一个Integer对象,所以他们是相等的,看源码:

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

②如果是不在这个范围的,则他们会创建两个Integer对象,所以不一样。

   public class Main {
    public static void main(String[] args) {
    Integer i1 = 100;
    Integer i2 = 100;
    Integer i3 = 200;
    Integer i4 = 200;  
    System.out.println(i1==i2);  //true
    System.out.println(i3==i4);  //false
    }
    }
(2)Integer跟int之间的比较:一定相等

因为如果一个封装类型(Integer)与一个基本数据类型==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。、

public class Main {
    public static void main(String[] args) {

		Integer i1 = 100;
		int i2 = 100;
		int i3 = 200;
		Integer i4 = 200;
		System.out.println(i1==i2);//true
		System.out.println(i3==i4);//true
	}
}
(3)Double与Double类型的比较

上面我们看到的Integer在比较的时候有一个-127~128范围内引用同一个对象,而超出这个范围之后就不再引用同一个对象。然而
在Double类型的时候并没有,这是因为浮点数据类型没有一个有限的集合里面,看源码:

   public static Double valueOf(double d) {
        return new Double(d);
    }

我们可以做如下总结:
①Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
②Double派别:Double、Float的valueOf方法的实现是类似的。每次都返回不同的对象。
所以Double创建的对象都是不一样的。所以不相等

public class Main {
    public static void main(String[] args) {

		Double i1 = 100;
		Double i2 = 100;
		double i3 = 100;
		double i4 = 100;
		System.out.println(i1==i2);//false
		System.out.println(i3==i4);//true
	}
}
(4)Double和double类型的比较

这个就跟Integer和int比较一样,封装类进行拆箱

2、equals的比较

(1)Double和double类型的比较

a.equals(b);要相等必须满足两个条件
①类型相同
②内容相同
首先来查看equals源码(我这里点开的是double的equals的源码):

 public boolean equals(Object obj) {
        return (obj instanceof Double)
               && (doubleToLongBits(((Double)obj).value) ==
                      doubleToLongBits(value));
    }

可以看到equals传入的是一个Object对象,
所以当我们执行下面代码的时候

public class Main {
    public static void main(String[] args) {

		Double i1 = 100;
		Double i2 = 100;
		double i3 = 100;
		double i4 = 100;
		System.out.println(i1.equals(i3));//true
		//System.out.println(i3==i4);
	}
}

首先因为传入的是一个基本数据类型,所以要进行装箱,将double转为Double,所以第一个类型相同就
满足了,接下来再比较两者的内容,可以看到都是100,也是一样的,所以两者相同。
其他的Integer类型也是一样的。

3、不同类型的比较

(1)Long和Int类型的"=="和“equals”比较

首先我们可以直接来试一下对long和int直接比较。
发现结果是正确的,然后我们再来进行Long和Integer进行比较,发现直接报不同对象不能比较,跳过。
然后我们再来看一下下面的程序
现在我们改成:

public class Main {
    public static void main(String[] args) {

		Integer num1 = 100;  
		int num2 = 100;  
		Long num3 = 200l;
		Integer num4 = 100;
		System.out.println(num3 == (num1 + num2));  //true
		System.out.println(num3.equals(num1 + num2));  //false
	}
}

①可以发现,本来两个不能比较的Long类型和Integer类型,经过一个加运算的时候,首先int和Integer相加
有一个是基本数据类型所以转为了int类型,然后Long num3==int (200),又是一个基本数据类型跟Long比较,转型
所以结果是true.
②而第二个结果是false,理所应当的,因为equals比较的还要两个类型相同,而num1+num2是Integer类型,所以
所以不一样。

猜你喜欢

转载自blog.csdn.net/tangyuan_sibal/article/details/86566687