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

包装类

优点:

  • 可以赋值为null
  • 提供了一系列的方法常用的有:parseInt(String s)、tostring()、valueOf(String s)、equals( object object)、i.compareto(integer anotherIntger)
  • 集合中不允许放基本数据类型,只能放包装类

缺点:

  • 由于每个值分别包装在对象中,所以ArrayList的效率远远低于int[]数组。(应该用其构造小型集合,其原因是程序员操作的方便性要比执行效率更加重要)

基本数据类型

优点:

  • 计算效率高
  • 不会由于常量池而引起比较大小的错误

缺点:

  • 当数据库查询出结果封装到结果集时,如何返回的值为null时,会将结果赋值给字段,运行时会报错,不能将null值赋值给基本数据类型。

两者的区别:

1、声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间;
2、存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用;
3、初始值不同,基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null
4、使用方式不同,基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到。
5、包装类都是继承Number 接口实现Compareble 接口的

自动装箱和自动拆箱

在Java中,数据类型可以分为两大类:Primitive Type(原始类型)和Reference Type(引用类型)。基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法。

自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int值转换成Integer对象,这个过程叫做装箱;反之将Integer对象转换成int值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱

自动装箱和拆箱的使用场景

自动装箱时编译器调用valueOf将原始类型值转换成对象,而自动拆箱时编译器通过调用类似intValue(),doubleValue()等的方法将对象转换成原始类型值。

/** 赋值时 **/
ArrayList intList = new ArrayList();
intList.add(1); //autoboxing -> primitive to object
intList.add(2); //autoboxing

ThreadLocal intLocal = new ThreadLocal();
intLocal.set(3); //autoboxing

int number = intList.get(0); // unboxing
int local = intLocal.get(); // unboxing in Java

/** 方法调用时 **/
public static Integer show(Integer iParam){
    System.out.println("autoboxing example - method invocation i: " + iParam);
    return iParam;
}

//autoboxing and unboxing in method invocation
show(4); //autoboxing
int result = show(4); //unboxing because return type of method is Integer

自动装箱和拆箱的注意点

1.避免生成无用对象增加GC压力
下例在一个循环中进行自动装箱操作,它创建了多余的对象,影响了程序的性能。

Integer sum = 0;
for(int i = 128; i < 5000; i++){
    sum += i;
}

“+”这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其内部变化如下:

    temp = sum.intValue() + i;
    Integer sum = new Integer(temp);

由于声明的sum为Integer类型,在上面的循环中会创建将近4900个无用的Integer对象,这增加了垃圾回收的工作量,降低了程序的性能。因此在我们编程时需要正确地声明变量类型,避免因为自动装箱和拆箱引起的性能问题。
2.对象初始化
当我们进行一个原始数据值与一个对象的比较时,如果这个对象没有进行初始化或者对象为null,在自动拆箱过程中会抛出NullPointerException异常,代码如下:

    private static Integer count;

    // NullPointerException on unboxing
    if(count <= 0){
        System.out.println("Count is not started yet");
    }

3.对象缓存
Java默认会对-128到127的Byte、Short、Integer和Long对象进行缓存,当创建的对象在这个数值范围则返回已缓存的对象,否则创建新的对象。Character缓存的范围是0~127,而Float和Double没有自动装箱池。这种设计了享元设计模式,详见享元模式。
然而,我们可以通过getAndRemoveCacheProperties方法来获取或移除JDK对Integer设置的缓存属性,同时可以通过调整虚拟机选项-XX:AutoBoxCacheMax来调整“自动装箱池”的大小 。
4.对象相等比较

    Integer integer1 = 100;  
    Integer integer2 = 100;  
    System.out.println("integer1==integer2: " + (integer1 == integer2));// true  自动装箱的两个缓存中的 Integer对象的引用比较  
    System.out.println("integer1.equals(integer2): " + (integer1.equals(integer2)));// true  
    System.out.println("integer1.compare(integer2): " + integer1.compareTo(integer2));// 0      
    Integer integer3 = 200;  
    Integer integer4 = 200;  
    System.out.println("integer3==integer4: " + (integer3 == integer4));// false 自动装箱的两个new Integer的引用比较  
    System.out.println("integer3>integer4: " + (integer3 > integer4)); // false 将两个对象拆箱,再比较大小  
    System.out.println("integer3.equals(integer4): " + (integer3.equals(integer4)));// true  
    System.out.println("integer3.compare(integer4): " + integer3.compareTo(integer4));// 0     
    Integer integer5 = new Integer(100);  
    Integer integer6 = new Integer(100);  
    System.out.println("integer5==integer6: " + (integer5 == integer6)); // false 两个不同的Integer对象引用的比较  
    System.out.println("integer5.equals(integer6): " + (integer5.equals(integer6)));// true  
    System.out.println("integer5.compare(integer6): " + integer5.compareTo(integer6));// 0      
    int int1 = 100;  
    System.out.println("integer1==int1: " + (integer1 == int1));// true  Integer缓存对象拆箱后与int比较  
    System.out.println("integer1.equals(int1): " + (integer1.equals(int1)));// true  
    System.out.println("integer1.compare(int1): " + integer1.compareTo(int1));// 0        
    int int2 = 200;  
    System.out.println("integer3==int2: " + (integer3 == int2));// true  Integer对象拆箱后与int比较  
    System.out.println("integer3.equals(int2): " + (integer3.equals(int2)));// true  
    System.out.println("integer3.compare(int2): " + integer3.compareTo(int2));// 0   

你可能感兴趣的:(java理论)