Java基础:数据类型会考什么?

本文列举一些关于Java基础的数据类型相关考点,方便以后复习查看

  • Java 中的哪几种基本数据类型了解么?它们的默认值和占用空间大小知道不? 说说这八种数据类型对应的包装类型
  • 基本类型和包装类型的区别?

  • int 和 Integer 的区别

  • 为什么要有包装类型 ? 

  • 包装类型的缓存机制了解么?

  • 自动装箱与拆箱了解吗?原理是什么?

  • 在哪些场景下,Java会自动拆装箱呢 ? 
  • 自动拆装箱会带来什么问题呢 ?
  • 遇到过自动拆箱引发的NPE问题么 ?
  • String 怎么转成 Integer 的?原理?

  • Java 中的哪几种基本数据类型了解么?它们的默认值和占用空间大小知道不? 说说这八种数据类型对应的包装类型

Java一共有八种数据类型分别为 byte short int long float double char boolean.

默认值 : byte-0 ,int-0 ,short-0, long-0L, float- 0.0f, double-0.0d char- '\u0000' , boolean-false

占用空间大小 : byte -1字节,short-2字节,int-4字节,long-8字节,float-4字节,double-8字节,char-2字节boolean-不确定.

对应的包装类型 : byte - Byte,int-Integer,short-Short,long-Long,float-Float,double-Double,boolean-Boolean.

  • 基本类型和包装类型的区别? 

默认值 : 基本类型都有自己的默认值,包装类型的默认值都是null

用于泛型 : 基本类型不能用于泛型,包装类可以用于泛型

存储区域 : 如果基本类型用于成员变量那存放在堆中,用于局部变量或者方法参数就会存放在Java虚拟机栈中. 而包装类型是对象类型(引用类型) 存放在堆中

占用空间 : 基本数据类型存放的数值都是在栈中,而包装类型在栈中存储对象的引用并且指向队中的对象, 相比于基本数据类型来说,包装类型要占用更多的内存空间

变量的比较不同 : 对于==来说,如果是基本数据类型比较的是值,如果是引用数据类型(包装类型)比较的是两个变量的地址是否相等,对于equals来说,如果引用类型没有重写equals与==一样,如果重写了比较的是内容-->包装类一般都默认重写了equals,建议引用类型(对象类型)使用equals比较.基本数据类型使用==比较

  • int 和 Integer 的区别

默认值 : int默认值为0,Integer默认值为null

泛型 : int不能用于泛型,Integer是包装类型可以用于泛型

数据类型区别 : int是基本数据类型,Integer是包装类型

存储方式不同 : int类型直接存放在Java虚拟机栈中的局部变量表中.而Integer类型属于对象类型,对象的实例都是存在于堆中的.相比于对象类型,基本类型占用的空间较小

实例化方式不同 : Integer需要实例化,int不需要

变量的比较不同 : 基本类型的比较相等使用==,包装类型使用equals比较的才是内容

  • 为什么要有包装类型 ? 

因为Java是属于面向对象的编程语言,很多地方都需要使用对象而不是基本数据类型,就比如Java集合类中 不允许将基本数据类型放进去,因为集合的容器要求元素是Object类型;

所以为了让基本数据类型也有面向对象特征,就出现了包装类型.相当于对基本数据类型做了一个包装,使其具有对象的性质,并添加了属性和方法,丰富了基本类型的操作.

基本数据类型都有对应的包装类型,两者可以进行互相转化,这个过程叫做拆箱和装箱.

  • 基本类型和包装类怎么进行选择呢 ? 

 阿里巴巴Java开发手册是这么说的

这里注意的是POJO类就是简单Java对象.

所以建议POJO类(Java对象)属性必须使用包装数据类型. 推荐所有的局部变量使用基本数据类型.

原因如下 :

很多业务场景下,对象的某些属性没有赋初始值,我们就希望它是NULL,如果给出赋一个初始值就会出现问题.

假设一个场景 :

我们现在要做一个扣费系统,需要专门调一个外部接口来计算 "费率",使用公式 金额*费率 得出花费的费用,然后根据这个计算结果进行扣费.

如果扣费系统出现了异常,费率就会返回一个默认值,如果是Double类型就返回null,就会直接中断程序不在往下执行,如果是double类型则返回0.0,这样就导致得出计算结果为0后,直接扣费了,这样系统异常就无法感知了

但如果要单独对0进行判断,又会引发出问题,如果允许费率为0的情况下扣费呢 ? 这样系统就无法识别出这个0是正常情况还是异常情况. 

所以使用基本数据类型会让方案越来越复杂,使用包装类定义变量,通过异常可以阻断程序的运行,可以识别出线上问题,如果使用基本数据类型,系统无感知,可能不会报错,认为是无异常.

  • 包装类型的缓存机制了解么?

Java中大部分包装类型都实现了缓存机制

Byte,Short,Integer,Long实现了缓存机制,这四种包装类创建了在[-127,128]范围内的缓存数据.  对于Character 创建了[0,127]范围内的缓存数据. Boolean直接返回True或者false,

而Float,Double则没有缓存机制.

  • 缓存的作用是什么 ? 

缓存的作用就是提高性能和节省内存-通过使用相同的对象引用实现了缓存与重用,

会在第一次使用包装类型的时候需要额外的一定时间来初始化这个缓存,下次如果使用的数字在缓存的范围内,可以直接使用相同的对象,不用在重新创建新的包装类对象了.IntegerCache缓存内部是使用for循环从低到高的创建整数,并把这些整数存到一个整数数组里面

对于Integer类比较特殊,在Java6中可以通过Integer.IntegerCache.high来设置最大值,使得我们可以根据应用程序的实际情况来调整数值提高性能. Byte,Short,Long 缓存范围固定不能改变

  • 那为什么 选择[-128,127]之间这个数值范围呢 ? 

因为这个数值范围是最被广泛使用的.在性能和资源之间做的一个权衡.

  • 自动装箱与拆箱了解吗?原理是什么?

自动装箱 : 将基本数据类型自动转换为对应的包装类

自动拆箱 : 将包装类自动转换为对应的基本数据类型

Integer i = 10;//自动装箱
int n = i;//自动拆箱

自动装箱的原理是使用包装类的valueOf()方法(比如Integer a = Integer.valueOf(10))

自动拆箱的原理是使用包装类的xxxValue()方法(比如 int b= Integer.intValue(a))

我们如果想使用包装类型的话建议使用valueOf因为这样如果用的数字在缓存范围内是直接从缓存中取,否则new是直接创建一个对象,没有利用缓存.没有节省内存.

  • Integer相关面试题
public static void main(String[] args) {
    //对象的比较强烈建议使用equals比较
    Integer in1= new Integer(127);//堆中
    Integer in2 = new Integer(127);//堆中
    System.out.println(in1==in2);//false (都是new的->两个不同的对象->地址不同)
    System.out.println(in1.equals(in2));//true (比较的是内容)

    //超过缓存范围不能重用对象
    Integer in3= new Integer(128);//堆中
    Integer in4 = new Integer(128);//堆中
    System.out.println(in3==in4);//false (都是new的->两个不同的对象->地址不同)
    System.out.println(in3.equals(in4));//true (比较的是内容)

    Integer in5= 128;//堆中
    Integer in6 = 128;//堆中
    System.out.println(in5==in6);//false (超过缓存范围不能重用对象)
    System.out.println(in5.equals(in6));//true  (比较的是内容)


    Integer in7= 127;//常量池中
    Integer in8 = 127;//常量池中
    System.out.println(in7==in8);//true (没有超出缓存范围可以重用对象)
    System.out.println(in7.equals(in8));//true (比较的是内容)


    Integer tt2 = Integer.valueOf(99);//常量池 利用的缓存
    int tt3 = 99;
    System.out.println(tt2 == tt3);// true
}
  • 在哪些场景下,Java会自动拆装箱呢 ? 
  1. 将基本数据类型放入到集合类中===>自动装箱(Integer.valueOf()方法)
  2. 包装类和基本数据类型大小比较时,先将包装类拆箱之后在进行比较.==>自动拆箱(xxxValue())
  3. 包装类的运算会被自动拆箱成基本数据类型进行运算
  4. 在使用三目运算符的时候,第二位,第三位操作数如果是基本类型和对象的时候其中对象就会被拆箱为基本数据类型.如果包装类对象为null,在自动拆箱的时候就会抛出NPE
  5. 在函数传参的时候,传参基本数据类型返回包装类==>自动装箱,传参包装类,返回基本数据类型==>自动拆箱
  • 自动拆装箱会带来什么问题呢 ? 
  1. 比较包装类型的时候不能简单的使用==,虽然-128,127范围内可以使用==,但是超出这个范围的数字还是需要equals
  2. 有些场景下,如果包装类对象为null,在自动拆箱的时候就会抛出NPE
  3. 如果一个for循环有大量的拆装箱动作,就会浪费很多资源.
  • 遇到过自动拆箱引发的NPE问题么 ? 

如果包装类对象为null,就会引发出NPE问题

  1. 比如数据库查询结果有可能查出为null,但使用基本数据类型接收就会触发自动拆箱就会NPE
  2. 在使用三目运算符的时候,第二位,第三位操作数如果是基本类型和对象的时候其中对象就会被拆箱为基本数据类型.如果包装类对象为null,在自动拆箱的时候就会抛出NPE
  • String 怎么转成 Integer 的?原理?

String 转成 Integer,主要有两个方法:

  • Integer.parseInt(String s)
  • Integer.valueOf(String s)

不管哪一种,最终还是会调用 Integer 类内中的parseInt(String s, int radix)方法.

public static int parseInt(String s, int radix)
                throws NumberFormatException
    {

        int result = 0;
        //是否是负数
        boolean negative = false;
        //char字符数组下标和长度
        int i = 0, len = s.length();
        ……
        int digit;
        //判断字符长度是否大于0,否则抛出异常
        if (len > 0) {
            ……
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                //返回指定基数中字符表示的数值。(此处是十进制数值)
                digit = Character.digit(s.charAt(i++),radix);
                //进制位乘以数值
                result *= radix;
                result -= digit;
            }
        }
        //根据上面得到的是否负数,返回相应的值
        return negative ? result : -result;
    }

使用一个数字累减,然后最后取反.

参考 :

Java 面试指南 | JavaGuide(Java面试+学习指南)

<<深入理解Java核心技术>>

面试官:int和Integer有什么区别?为什么要有包装类? - 掘金

面渣逆袭必看,面试题八股文JavaSE、Java 集合框架、Java 并发编程、JVM、Spring、Redis、MyBatis、MySQL、操作系统、计算机网络、RocketMQ、分布式👍 | Java程序员进阶之路

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值