java常见面试题:基本数据类型和包装类的全部知识点

本文结构如下:

  1. 什么是基本数据类型
  2.  什么是包装类
  3. 两者的区别以及使用场景
  4. 什么是自动装箱拆箱
  5. 整型常量池

1.什么是基本数据类型

java 中的对象很多都是朝生夕死的(gc回收),所以一直放在堆中不是很高效。因此为方便基本类型的数据计算,java创造了八种基本数据类型:整型byte, short, int, long, 浮点型double, float, 字符型char, 布尔型boolean

基本数据类型

默认值

包装类

byte

0

Byte

short

0

Short

int

0

Integer

long

0L

Long

float

0.0f

Float

double

0.0d

Double

char

‘\u0000’(其实就是0)

Character

boolean

false

Boolean

1.1 整型:

byte属于Java中的整型,长度为1字节8bit,取值10000000(-128)到 01111111(127),变量初始化默认值为0;

short属于Java中的整型,长度为2字节16bit,取值10000000 00000000(-32768)到 01111111 11111111(32767),变量初始化默认值为0;

int属于Java中的整型,长度为4字节32bit,取值-2^31 (-2,147,483,648)到 2^31-1(2,147,483,647),变量初始化默认值为0;

long属于Java中的整型,长度为8字节64bit,取值-2^63 (-9,223,372,036,854,775,808‬)到 2^63-1(9,223,372,036,854,775,8087),变量初始化默认值为0或0L。

1.2 浮点型:

java 的浮点类型都依据 IEEE 754 标准。IEEE 754 定义了32 位和 64 位双精度两种浮点二进制小数标准。

IEEE 754 用科学记数法以底数为 2 的小数来表示浮点数。32 位浮点数用 1 位表示数字的符号,用 8 位来表示指数,用 23 位来表示尾数,即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制(底数 2 )小数来表示。对于64 位双精度浮点数,用 1 位表示数字的符号,用 11 位表示指数,52 位表示尾数。

浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用 float 和 double 作精确运 算的时候要特别小心。

浮点型精确性验证可参考这篇文章:https://zhidao.baidu.com/question/692123529504139004.html

1.3 字符型:

char属于java中的字符型,占2字节16bit,可以赋值单字符以及整型数值。

1.4 布尔值:

在JVM中并没有提供boolean专用的字节码指令,而boolean类型数据在经过编译后在JVM中会通过int类型来表示,此时boolean数据4字节32位,而boolean数组将会被编码成Java虚拟机的byte数组,此时每个boolean数据1字节占8bit。

布尔值仅有两个值true, false,变量初始化默认值false

1.5 基本数据类型转换注意点:

低精度数据类型可直接转高精度数据类型,高精度数据类型得强转低精度数据类型,且会造成数据失真。

int a = 2147483647;
long b = a;//低精度可直接转高精度
b++;
int c = (int) b;//高精度强转低精度,数据失真

例如:正方形也属于长方形,但长方形转为正方形就得切去部分面积。

 

2.什么是包装类

Java 是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型,它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

2.1 特点

包装类统一继承抽象类Number,并且实现了Comparable接口

包装类都是final,而且成员变量都是static final

2.2 构造方式

1)通过直接赋值 Integer i=1;

2)构造器 Integer i=new Integer(1);

3)静态工厂valueOf方法 Integer i=Integer.valueOf(1);

 

3. 两者的区别以及使用场景

3.1 区别:

包装类可以为null,而基本类型不行。

基本类型有默认值,包装类默认都为null。

基本数据类型存在栈中,包装类存在堆中需要通过地址引用,基本数据类型使用效率更高。

3.2 对象属性必须使用包装类型

数据库的查询结果可能是 null,如果对象属性使用基本类型的话,把null返回给基本数据就会报错。

举例:Student对象类中的成绩score属性值为0,如果成绩是基本类型,可能是考了0分,可能是没考,会有歧义。但如果成绩是包装类型,那说明是考了0分,没考值是null。

3.3 泛型必须使用包装类型

因为泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类——基本类型是个特例。

3.4 基本类型比包装类型高效

基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。包装类型需要占用更多的内存空间。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过 new 一个包装类型就显得非常笨重。

3.5 两个包装类型的值可以相同,但却不一定相等

总结:对象类及泛型必须使用包装类型,其他场景比如局部变量时,使用基本数据类型更高效。

3.6 方法参数为包装类型则允许空值

接口参数如果是包装类,不传就会报错。而如果接口参数是基本类型,参数不传不会报错,因为基本类型是有默认值的。

 

4. 什么是自动装箱拆箱

既然有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

Java SE5 为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能。

如下两行基本数据类型和包装类的转换:

Integer chenmo = 10;
//实际执行的代码:Integer chenmo = Integer.valueOf(10);
int wanger = chenmo;
//实际执行的代码:int wanger = chenmo.intValue();

自动装箱是通过 Integer.valueOf() 完成的;自动拆箱是通过 Integer.intValue() 完成的。

 

5. 整型常量池

先看两组判断:

Integer c = 100;
Integer d = 100;
System.out.println(c == d);//true

Integer c = 200;
Integer d = 200;
System.out.println(c == d);//false

输出为什么会有不同,我们看一下Integer赋值方法valueOf的源码:

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

这里存在一个IntegerCache缓存池,当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象。IntegerCache的源码如下:

/**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

有不足之处请多指教~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值