首先来看一段代码:
class Demo_04
{
public static void main(String[] args)
{
System.out.println(test(100,100));
System.out.println(test(500,500));
}
public static boolean test(Integer a,Integer b){//自动装箱
return a == b;
}
}
输出结果如下
看到这个结果有没有很奇怪?
下面对这个结果做一下分析:
首先,实际参数100是基本数据类型的整数类型,当调用静态方法test进行传参时,test方法的参数类型是整型的包装类Integer,因此在对test方法传参时,会进行自动装箱(基本数据类型转换为包装类成为装箱,反过程称为拆箱,jdk1.5之后可以自动将基本数据类型转换为包装类,因此成为自动装箱)。
我们应该清楚,基本数据类型包装类是引用类型变量,当进行自动装箱的过程中,java底层会对数值进行判断,当数值在-128到127时,此时应用变量所指向的是系统提前已经存在于的常量池中的100,也就是说,只要是-128到127范围内的数值,已经在常量池中存在了,不需要再去创建对象赋值之后再用引用变量指向了(java之父所规定的,他认为这个范围内的数是常用的);当数值不在这个范围之内时,再去创建对象。这样的话,程序中参数是100时,a和b指向的都是常量池中的100,因此地址值相同,==比较的是两者的地址值,因此返回true。而参数是500时,a和b指向的是不同的对象,因此地址值不同,返回false。
String类型的数值也有类似的情况
以代码为例:
class Demo_01
{
public static void main(String[] args)
{
String s = "abc";//字符串常量 一经创建 不能被改变
s = "kk";
System.out.println(s);
String ss = new String("ff");
System.out.println(s.equals(ss));
System.out.println(s==ss);//地址值 false
}
}
首先字符串常量一经创建,就不能被改变,它会存在于内存的常量池内,当初始化另一个字符串常量时,在存储之前,会去常量池查找,如果常量池中存在值相同的字符串常量,就不会创建新的,该对象直接指向已经存在的,如果没有再去创建新的。