以下内容是自己的学习笔记整理,如有错误,望大家指正!
引用:
(1) 引用可以看作是一种数据类型(保存在stack中),保存了对象在内存(heap,堆空间)中的地址,它和类实例(对象)是不一样的;
(2) 不同的引用可能指向同一个对象,换句话说,一个对象可以有多个引用,即该类类型的变量。比如说String a = “hello”; String b = “hello”;这时候a和b都指向了对象“hello“<注意:字符串是对象>
包装类:
Java提供的包装类分为两种:一种是对象型包装类(不继承任何其他类(Object的直接子类),包括Boolean、Character),另一种是数值型包装类(继承于Number类,包括Byte、Short、Integer、Long、Float、Double)
拆箱与装箱:
装箱:
将基本数据类型封装为包装类对象,利用每一个包装类提供的构造方法实现装箱操作。例如:Integer integer1 = 1;
拆箱:
将包装类中包装的基本数据类型数据取出。int integer2 = integer.;
自动装箱的内存复用:
自动装箱时,对于Integer x= ?,如果var指向的对象在-128~127范围内的赋值时,生成的Integer实例化对象是由 IntegerCache.cache() 方法产生,它会复用已有对象。和String的共享池操作是一个道理,cache()方法会将位于-128~127范围内产生的Integer对象入池,下次使用的时候,从池中拿去,就不会在创建了。
(常量池) 对于Integer、Short、Byte、Character、Long 这些包装类,都有一个常量池,常量池的范围是-128~127之间。如果定义的包装类的值在这个范围内,则会直接返回内部缓存池中已经存在的对象的引用,而对于浮点型Float和Double这样的包装类,没有常量池机制,不管传入的值是多少,都会new一个新的对象。
而对于手动装箱,即采用new进行包装类创建时,不会发生内存复用,因为new关键字每次使用,都会开辟新的空间,这和String采用构造 方法创建字符串不入池相对应。
以上内容参考于:https://blog.csdn.net/weixin_40739833/article/details/80093527
类型1 | 类型2 | 1和2是否相同类型 | == | equals | |||
基本数据类型 | 基本数据类型 | 是 | 值比较 | 无equals方法equals是Object类的方法, | |||
基本数据类型 | 基本数据类型 | 否 | 值比较 | 无equals方法 | |||
对象 | 对象 |
| 地址比较 | 如果有重写、按重写后的来,没有重写、等价于== | |||
包装类(Integer、Short、Byte、Character、Long) | 包装类(Integer、Short、Byte、Character、Long) | 是 | 进行是引用比较;一定范围内的不会新new,超过范围就会new一个新的 | 两边类型相同,如都是integer,则进行值比较。两边类型不同(一个Integer,一个Long)直接返回false | |||
包装类(Float、Double) | 包装类(Float、Double) | 是 | 无范围之说,每次都会new一个新的,所以返回的必定是false | 两边类型相同,如都是Double,则进行值比较。两边类型不同(一个Double,一个Long)直接返回false | |||
基本数据类型 | 包装类型 | 否(Integer和long) | 会自动进行拆箱进行值比较,会进行自动向上转型再比较值 | 自动装箱进行比较,两边类型不同,直接返回false | |||
基本类型 | 包装类型 | 是(Integer和Integer) | 会自动进行拆箱进行值比较 | 自动装箱进行比较,两边类型相同,如都是integer,则进行值比较 |
举例说明:
package test;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
int x =1;
int y = 1;
System.out.println(x==y); //基本数据类型值比较
//System.out.println(x.equals(y)); 基本类型没有equals方法
Integer a = 1;
Integer b = 2;
System.out.println(a==b);//自动拆箱 进行值比较 false
System.out.println(a==1);//值比较 true
System.out.println(a.equals(b));//自动拆箱 进行值比较 false
Integer c = 128;
Integer d = 128;
System.out.println(c==d);//进行的是引用比较 超过范围会new一个 所以为false
System.out.println(c.equals(d));//true 自动拆箱 进行值比较
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1==d2);//false 每次Double和Float都会new一个 即使值一样也会返回false
System.out.println(d1.equals(d2));//true 两边都是Double 会去比较值
System.out.println(b==(d1+1));//true d1自动拆箱编程double类型进行运算
System.out.println(b.equals(d1+1));//false d1自动拆箱编程double类型进行运算之后会自动装箱 因为equals是Object类型才有的方法,所以要装箱
//自动装箱后 两边类型不一致 直接返回false
System.out.println(y==a); //true 基本类型和包装类型 会自动进行拆箱进行值比较
System.out.println(a.equals(y)); //true 基本类型和包装类型 自动装箱进行比较,两边类型相同,如都是integer,则进行值比较。
long z=1;
System.out.println(z==a);//true 基本类型和包装类型 会自动进行拆箱进行值比较,会进行自动向上转型再比较值
System.out.println(a.equals(z)); //false 基本类型和包装类型 自动装箱进行比较,自动装箱进行比较,两边类型不同,直接返回false
}
}