1 基本数据类型
1.1 取值范围
1.2 精度问题
自动类型转换
容量小的类型自动转换成容量大的数据类型。 byte、short、int,它们三者在计算时会转成int类型 如果把int值转换成float值,或者long转换成double值,不需要强制转换,但可能丢失精度。
强制类型转换
容量大的数据类型转换成容量小的数据类型时,要加上强制类型转换符。 例:
short b = 10;short a = 1;a = (short)(a+b)
2 包装类
包装类为了解决基本类型不具备“对象”特性的问题。
基本数据类型和包装类型的区别—
- 包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是;
- 声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间;
- 存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们,因此,包装类的效率会比基本数据类型的效率要低。
- 初始值不同,比如:int的初始值为0、boolean的初始值为false,而包装类型的初始值为null;
3 自动拆装箱
即包装类和基本类型的转换
3.1 装箱
根据数据创建对应的包装对象。
Integer i = new Integer(3);//手动装箱
Integer i = Integer.valueOf(3);//手动
Integer j = 4;//jdk1.5 之后可以通过这种方式自动装箱
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。
Integer sum = 0;
for(int i=1000; i<5000; i++){
sum+=i;
}
上面的代码sum+=i可以看成sum = sum + i,但是+这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下
int result = sum.intValue() + i;
Integer sum = new Integer(result);
由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近多个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题。
3.2 拆箱
int index2 = j.intValue();//手动拆箱
int index1 = j;//自动拆箱
4 ==/equals()/hashcode()
4.1 ==
对于基本类型是值比较,对于引用类型来说是引用比较。
4.1.2 常量池
在java中,为了避免频繁的创建和销毁对象影响系统的性能,引入了常量池,通过常量池实现了对象的共享。 通过常量池,从而实现了以下好处:
- 节省内存空间,常量池中所有的相同对象会被合并,只占一个对象的空间。
- 节省运行时间,通过==对字符串比较,速度比equals()快。(在基本数据类型中,==比较的是数值;在复合数据类型中,比较的是内存地址。)
4.2 equals()
equals是原始类Object的方法,即所有对象都有equals方法,默认情况下(即没有重写)是引用比较,但是JDK中类很多重写了equals方法,String 和 基本类型封装类就重写了 equals,从而进行的是内容的比较;
4.3 hashCode()
hashcode()也是Object的方法,是一个本地方法,用C/C++语言实现的,hashcode是根据对象的内存地址经哈希算法得来的。
4.4 比较
equal()相等的两个对象他们的hashCode()肯定相等。hashCode()相等的两个对象他们的equal()不一定相等。
equals 和 hashCode 都可用来判断两个对象是否相等,但是二者有区别
equals可以保证比较对象是否是绝对相等,即「equals保证可靠性」hashCode用来在最快的时间内判断两个对象是否相等,可能有「误判」,即「hashCode保证性能」- 两个对象
equals为 true 时,要求hashCode也必须相等 - 两个对象
hashCode为 true 时,equals可以不等(如发生哈希碰撞时)
hashCode 的「误判」指的是
- 同一个对象的
hashCode一定相等。 - 不同对象的
hashCode也可能相等,这是因为hashCode是根据地址hash出来的一个int 32位的整型数字,相等是在所难免。
4.5 为什么重写了equals方法,就必须重写hashcode?
- 官方说法是:对象的equals方法被重写,那么对象的hashCode()也尽量重写;(主要看应用场景)
- equals 方法 和 hashCode 方法本身并没有紧密的联系,只是应用场景(如HashMap、HashSet等集合类的存取)使它们出现在了一起,才有了这句话;
- 哈希集合(如HashMap)要保证元素唯一性。key对象放入集合,先经过hash运算,得到index,找到数组对应位置,还要和此位置的对象进行比较(先用hash比较,后用equals方法),不一样就插入到后面形成链表,一样的话就不用插入了。重写了equals()方法,但不重写hashcode()方法,那可能两个相同的对象放入到了不同的位置,元素的唯一性就不存在了。