2019独角兽企业重金招聘Python工程师标准>>>
第一个例子:
假设我们同时定义
int a = 3;
int b = 3;
编译器先处理int a = 3;
首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。
接着处理int b =3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。
这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。
第二个例子 :
栈数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
String是一个特殊的包装类数据。可以用:
String str = new String(“abc”);
String str = “abc”;
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对 String类的对象引用变量str,然后查找常量池有没有存放”abc”,如果没有,则将”abc”存放进常量池,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。解释:常量池属于方法区的一部分
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
第三个例子 :
String str1 = “abc”;
String str2 = “abc”;
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。
String str3 =new String (“abc”);
String str4 =new String (“abc”);
System.out.println(str4==str3); // false
用new的方式是生成不同的对象。每一次生成一个。
因此用第一种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间.
对于String str = new String(“abc”);的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。所以new出来的对像他们的堆内存地址不相同,如果想对两个在堆内存中的变量进行比较的话,我们可以使用String类提供的equal()方法
三:Integer和int的特殊之处
int是基本数据类型,初始值是0;Integer是int的包装类,初始值是null
当讲一个int的值赋给Integer对象的时候,会进行自动装箱
Integer a = 10;
其实进行的是:
Integer a = Integer.valueOf(10);
我们看一下jdk提供的api查看一下Integer的源代码:
/*** Returns an {@code Integer} instance representing the specified* {@code int} value. If a new {@code Integer} instance is not* required, this method should generally be used in preference to* the constructor {@link #Integer(int)}, as this method is likely* to yield significantly better space and time performance by* caching frequently requested values.* * This method will always cache values in the range -128 to 127,* inclusive, and may cache other values outside of this range.* * @param i an {@code int} value.* @return an {@code Integer} instance representing {@code i}.* @since 1.5*/
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
private static class IntegerCache {private IntegerCache() {}static final Integer cache[] = new Integer[-(-128) +127 + 1];static {for (int i = 0; i < cache.length; i++) {cache = new Integer(i - 128);}}
}
当数值介于-128到127之间的数,会进行缓存所以Integer a = 127,Integer b = 127 ;a == b (true)。但是当数值大于127的时候两个对象的内存位置不一样。
int和Integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比(因为在Integer进行了拆箱之后:是int和int 相比;拆箱方法:intValue())
但是Integer a = new Integer(12); Integer b = new Integer(12);不相等