Skip to content

Latest commit

 

History

History
131 lines (102 loc) · 6.59 KB

1.基本数据类型.md

File metadata and controls

131 lines (102 loc) · 6.59 KB
title shortTitle isOriginal
1.基本数据类型
1.基本数据类型
true

本文已收录于:https://github.com/danmuking/all-in-one(持续更新)

八种基本数据类型

  • 6 种数字类型:
    • 4 种整数型:byte/8bitshort/16bitint/32bitlong/64bit
    • 2 种浮点型:float/32bitdouble/64bit
  • 1 种字符类型:char/16biy
  • 1 种布尔型:boolean/1bit

包装类型

为什么会有包装类型

Java 语言是一个面向对象的语言,讲究一切皆对象,但是 Java 中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了能够形成设计上的统一,Java 为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class),对应关系如下表:

基本类型 大小 包装器类型
boolean / Boolean
char 16bit Character
byte 8bit Byte
short 16bit Short
int 32bit Integer
long 64bit Long
float 32bit Float
double 64bit Double
void / Void

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

  • 用途:除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。并且,包装类型可用于泛型,而基本类型不可以
  • 存储方式:基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,包装数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。(包装数据类型本质上是类,遵守类的规则)
  • 占用空间:相比于包装类型(对象类型), 基本数据类型占用的空间往往非常小
  • 默认值:成员变量包装类型不赋值就是 null ,而基本类型有默认值且不是 null。
  • 比较方式:对于基本数据类型来说,==比较的是值。对于包装数据类型来说,==比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用equals()方法。

基本类型和包装类型的转换

在 Java 中,我们经常会这样给包装类型赋值

Integer i = 10;

这就涉及到一个问题,10是一个基本数据类型,Integer是一个包装类型,也是一个对象。正常情况下,一个基本数据类型肯定是没有办法给一个对象赋值的。因此,这里 Java 一定进行了一次隐式的类型转换,这个过程就是自动装箱和拆箱。

自动装箱与拆箱

什么是自动拆装箱?

  • 装箱:将基本类型用它们对应的引用类型包装起来;
  • 拆箱:将包装类型转换为基本数据类型;

举例:

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

上面这两行代码对应的字节码为:

   L1

    LINENUMBER 8 L1

    ALOAD 0

    BIPUSH 10

    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;

    PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;

   L2

    LINENUMBER 9 L2

    ALOAD 0

    ALOAD 0

    GETFIELD AutoBoxTest.i : Ljava/lang/Integer;

    INVOKEVIRTUAL java/lang/Integer.intValue ()I

    PUTFIELD AutoBoxTest.n : I

    RETURN

从字节码中,我们发现装箱其实就是调用了 包装类的valueOf()方法,拆箱其实就是调用了xxxValue()方法。 因此,

  • Integer i = 10等价于Integer i = Integer.valueOf(10)
  • int n = i等价于int n = i.intValue();

如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作。

包装类型的缓存机制

Java 基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。 Byte,Short,Integer,Long这 4 种包装类默认创建了数值 [-128,127]的相应类型的缓存数据,Character创建了数值在 [0,127]范围的缓存数据,Boolean直接返回True or False

只有基于valueOf()实现的方法能够利用到缓存机制,如果直接创建一个对象,例如new Integer(1)将会创建一个新的对象,没有办法利用缓存来提升性能。

类型转换

自动类型转换

转换自动类型转换(自动类型提升)是 Java 编译器在不需要显式转换的情况下,将一种基本数据类型自动转换为另一种基本数据类型的过程。这种转换通常发生在表达式求值期间,当不同类型的数据需要相互兼容时。自动类型转换遵循以下规则:

  • 如果任一操作数是 double 类型,其他操作数将被转换为 double 类型。
  • 否则,如果任一操作数是 float 类型,其他操作数将被转换为 float 类型。
  • 否则,如果任一操作数是 long 类型,其他操作数将被转换为 long 类型。
  • 否则,所有操作数将被转换为 int 类型。

需要注意的是,自动类型转换只发生在兼容类型之间。例如,从较小的数据类型(如 int)到较大的数据类型(如 long 或 double)的转换是安全的,因为较大的数据类型可以容纳较小数据类型的所有可能值。

规则如下:

byte -> short -> int -> long -> float -> double
char -> int -> long -> float -> double

强制类型转换

强制类型转换是 Java 中将一种数据类型显式转换为另一种数据类型的过程。与自动类型转换不同,强制类型转换需要程序员显式地指定要执行的转换。强制类型转换在以下情况中可能需要:

  • 将较大的数据类型转换为较小的数据类型。
  • 将浮点数转换为整数。
  • 将字符类型转换为数值类型。

需要注意的是,强制类型转换可能会导致数据丢失或精度降低,因为目标类型可能无法容纳原始类型的所有可能值。因此,在进行强制类型转换时,需要确保转换后的值仍然在目标类型的范围内。

下面是一个简单的例子:

double doubleValue = 42.8;

// 强制类型转换:将 double 类型转换为 int 类型
int intValue = (int) doubleValue;
System.out.println("整数值: " + intValue); // 输出:整数值: 42

这段代码将一个double类型的变量doubleValue值强行赋给为int类型的变量intValue,在这个过程中,由于int类型无法表示小数部分,因此小数部分将被截断。

总结

虽然这部分知识点在面试中很少出现,但是一旦答不上来,面试官很容易就给你打上一个基础不扎实的标签。所幸这部分知识点其实也不多,所以还是尽量花点时间看一看。