007-014:关于包装类的面试题

007:如何理解Java中的包装类?

Java的类型系统由两部分组成:基本类型(primitive)和引用类型(reference type)。包装类指的是Java基础类型对应的引用类型。每个基本类型都有一个对应的包装类:

  • boolean、byte、short、char、int、long、float、double

  • Boolean、Byte、Short、Character、Integer、Long、Float、Double

基本类型和包装类型有三个区别:

  1. 基本类型只有值,而包装类型则是一个对象,也就是说,两个包装类型的对象,它们的值相同,但是对象地址可以不同;

  2. 包装类型除了拥有基本类型的功能外,还可以表示null的概念;

  3. 基本类型通常比包装类型更省时间和空间。

008:为什么Java需要包装类这个概念?

在Java中的泛型类不支持基本类型,只支持引用类型,因此,如果我们希望在泛型类中使用基本类型,就需要将基本类型先转换成引用类型。例如:Java集合框架只能存放引用类型的元素。

009:创建包装类实例的方式有哪些?

将基本类型转换成引用类型的方式有两种:构造方法、静态工厂方法。这里看一个将int值转换成Integer对象的例子,代码如下:

Integer object = new Integer(1); 

Integer anotherObject = Integer.valueOf(1); 

这两种转换方式对于int转Integer有区别:valueOf方法会优先返回缓存的数据([-128,127]),如果超出这个范围,才会使用构造方法创建包装类型。valueOf的代码如下:

public static Integer valueOf(int i) { 
    if (i >= IntegerCache.low && i <= IntegerCache.high) 
        return IntegerCache.cache[i + (-IntegerCache.low)]; 
    return new Integer(i); 
} 

另外,如果需要从一个包装类型转换成基本类型,则需要使用相关的方法,例如:intValue()doubleValue()等等:

int val = object.intValue();

010:如何理解自动装箱?

在Java 1.5之前,开发者必须手动处理包装类型和基本类型之间的转换,例如要在一个集合中放入整数的时候,直接调用coll.add(5)是不支持的。

Java 1.5增加了自动装箱(autoboxing)和自动拆箱(auto-unboxing)的特性,可自动完成包装类型和基本类型的转换。自动装箱指的是自动将一个基本类型转换成包装类型对象。

什么时候会发生自动装箱呢?

  • 在执行方法调用时,传递一个基本类型的值给到一个方法参数为包装类型的方法中

  • 将一个基本类型的值赋值给一个包装类型对象。

上述两种情况的例子代码如下:

List<Integer> list = new ArrayList<>(); 

list.add(1); //自动装箱 

Integer val = 2; //自动装箱 

011:自动装箱有什么好处?

自动装箱有助于提高代码的可读性。

不过在一些情况下,却不推荐自动装箱特性,例如:在循环中,下面的代码比预计的运行起来要慢一点:

public static void main(String[] args) { 
    Long sum = 0L; 
    for (long i = 0; i < Integer.MAX_VALUE; i++) { 
        sum += i; //sum被不断得自动拆箱和装箱 
    } 
    System.out.printfln(sum); 
} 

012:如何理解类型转换?

类型的转换是在等号左边和等号右边的变量数据类型不一致的时候发生,这时候需要将一个数字从一个数据类型转换成另一种数据类型。数据类型的转换可以分为隐式转换(自动类型转换)和显式转换(强制类型转换)两种。

013:如何理解隐式转换?

隐式转换需要满足两个条件:

  1. 两种数据类型兼容

  2. 目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)。例如:byte类型的数据赋值给short类型的变量时,由于short类型的取值范围比较大,这里会发生隐式转换

数据类型的级别规定如下(从左到右的转换顺序):

  • 数值类型的数据转换:byte——>short——>int——>long——>float——>double

  • 字符类型转换为整数:char——>int

014:如何理解显式转换?

当两种类型的数据不兼容时,或者目标类型的取值范围小于源类型时,就无法进行隐式转换,这时候就需要进行显式转换(强制类型转换),例子代码如下:

int a = 3; 
double b = 5.5; 
a = (int)b;//显式转换,会丢精度 

参考资料

  1. https://www.baeldung.com/java-wrapper-classes
  2. 《Effective Java》
  3. http://c.biancheng.net/view/796.html
  4. https://www.baeldung.com/java-type-casting
  5. https://www.baeldung.com/java-primitive-conversions

阿杜

蚂蚁金服、CRUD研究者

发表评论

电子邮件地址不会被公开。 必填项已用*标注