Java基础-数据类型

144 阅读5分钟

1 基本数据类型

1.1 取值范围

image.png

1.2 精度问题

image.png

自动类型转换

容量小的类型自动转换成容量大的数据类型。 byte、short、int,它们三者在计算时会转成int类型 如果把int值转换成float值,或者long转换成double值,不需要强制转换,但可能丢失精度。

强制类型转换

容量大的数据类型转换成容量小的数据类型时,要加上强制类型转换符。 例:

short b = 10;short a = 1;a = (short)(a+b)
  • 精确值(byte、char、short、int、long)转化成相似值(float、double)时有可能造成精度降低或者数据溢出,使用时要小心。
  • boolean类型不能转化成任何其他数据类型。

2 包装类

包装类为了解决基本类型不具备“对象”特性的问题。

基本数据类型和包装类型的区别

  1. 包装类是对象,拥有方法和字段,对象的调用都是通过引用对象的地址,基本类型不是;
  2. 声明方式不同,基本数据类型不需要new关键字,而包装类型需要new在堆内存中进行new来分配内存空间;
  3. 存储位置不同,基本数据类型直接将值保存在值栈中,而包装类型是把对象放在堆中,然后通过对象的引用来调用他们,因此,包装类的效率会比基本数据类型的效率要低。
  4. 初始值不同,比如: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中,为了避免频繁的创建和销毁对象影响系统的性能,引入了常量池,通过常量池实现了对象的共享。 通过常量池,从而实现了以下好处:

  1. 节省内存空间,常量池中所有的相同对象会被合并,只占一个对象的空间。
  2. 节省运行时间,通过==对字符串比较,速度比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()不一定相等。

equalshashCode 都可用来判断两个对象是否相等,但是二者有区别

  • 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()方法,那可能两个相同的对象放入到了不同的位置,元素的唯一性就不存在了。