一、equals和 ==
equals是对象的比较方法,因此我们在这里讨论的对象才有意义。
两者区别
==: 是比较变量是否相同,其中包括基本数据类型的值和引用型变量(Object),前者比较值是否相等,后者比较地址是否一致。
equals:只比较对象按某种规则下某方面是否相等,比较规则具体根据重写的euqals方法分析。
(Java提供的所有类中,绝大多数类都重写了equals()方法,重写后的equals()方法一般都是比较两个对象的值,比如String类,Date类,基本数据类型的包装类等。)
String对象创建方式:java中存在常量池,存放了开辟字符串的公共内存,无论用什么方式创建字符串,都会先到常量池,可以理解为一种内部字符串常量表,记录着已有名值对,如果已存在想要用的字符串,则直接返回字符串对象,否则在常量池里新创建完后再返回。
1、字面值方式
//s1 == s2 true
本质上是隐式调用了String s1 = String.valueOf("abc")初始化对象,指向相同,地址相同
2、new方式
//s1 == s2 false
同样每次创建都需要在常量池中寻找一遍,不存在便新创建,存在便返回"abc"的字符串对象,虽然构造参数使用相同的字符串,但凡是用new声明的对象都是存放在堆内存中的,位于不同的位置,他们的地址并不相同。
以上例子的euqals都为true。
二、包装类
java中的基本类型没有方法和属性,而包装类就是为了让这些拥有方法和属性,实现对象化交互
包装类的缓存问题和String的常量池非常相似。
下面简单描述一下:
整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理。当然其目的就是提高效率。
缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。
此处以Integer类为例,源码参考:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); // 超过范围就是new的Integer对象
}
// 隐式调用 包装方法Integer.valueOf(100)
常用的:
通过包装类Integer.toString()将整型转换为字符串;
通过Integer.parseInt()将字符串转换为int类型;