Java中8种基本类型与相应的包装类

220 阅读4分钟

1.8种基本类型

  • 上图可以看出Java的数据类型分为基本数据类型和引用数据类型,下面介绍8种基本数据类型。

1.1.整数类型

类型占用空间范围
byte(字节)1字节-128~127
short(短整型)2字节-2^15~2^15-1
int(整型)4字节-2^31~2^31-1
long(长整型)8字节-2^63~2^63-1
  • 整数类型使用细节:

Java声明的整型常量默认为int型,声明long型常量的话必须在后面加 "l"或"L"

1.2.浮点类型

类型占用空间范围
float(单精度)4字节-3.403E38~3.403E38
double(双精度)8字节-1.798E308~1.798E308
  • 浮点类型使用细节:

    • 浮点数在机器中的存放形式:符号位+指数位+尾数位
    • 尾数部分可能丢失,造成精度损失(小数都是近似值)
    • Java声明的浮点类型默认为double型,声明float型常量须在后面加 "f"或"F"
float f = 1.1;//错误

float f1 = 1.1f;//正确

double d = 1.1f;//正确
  • 浮点型常量有两种表示形式:

    • 十进制:double d = 0.23/0.23f/.23;

    • 科学计数法

double d4 = 1.23e2;//相当于123.0

System.out.println("d4 = "+ d4);

通常情况下推荐使用double,因为它比float 更精确**

double d5 = 1.23456789;

float  f2 = 1.23456789f;

System.out.println("d5 = "+ d5);

System.out.println("f2 = "+ f2);

  • 浮点类型使用陷阱
double d6 = 2.1 / 3;//认为是0.7

System.out.println(d6);//输出的是一个近似0.7的小数



double d7 = 0.7;

System.out.println(d6 == d7);//false

原因:计算机在存储小数时会有精度的误差

总结出:在对运算结果是小数的量进行判断时,不能直接判断可能有误差,建议的方法是以两个数的差值的绝对值在某个精度内进行判断

if (Math.abs(d6 - d7) < 0.0000001){ 

    System.out.println("可以认为两数相等");

}

1.3.字符类型

类型占用空间范围
char2字节0~2^16-1

char,存放单个字符

  1. 使用细节

    1. 字符类型也可以直接存放一个整数,输出时会输出unicode码对应字符
char a = 97;

System.out.println(a);

  1. char的本质是一个整数,在输出时输出对应unicode码对应的字符
  2. char可以进行运算,值相当于字符对应的unicode码

1.4.布尔类型

类型占用空间范围
boolean1字节或4字节true/false
  1. boolean类型只允许取值true和false,没有null
  2. 不可以用0和非0的整数代替true和false

1.5.基本类型数据转换

  1. 自动类型转换

在进行运算时,精度小的类型自动转化为精度大的类型,转换排序如下图

  • (byte、short)和char 不会相互自动转换
  • byte、short 和 char 参与运算时,当作 int 类型处理
  • 自动提升原则:表达式结果的类型会自动提升为操作数中最大的类型
  1. 强制类型转换

    1. 自动类型转换的逆过程,使用时要加上强制转换符 (),可能造成精度损失或溢出
    2. 强转符号只对最近的操作数有效,多使用小括号提升优先级
int x = (int)2.5*2;

int y = (int)(2.5*2);

System.out.println(x+"\t"+y);

  1. char类型在保存int的变量值时需要强转
int i = 100;

char c = i;//错误

char c1 = (int)i;//正确

2.包装类

2.1.包装类的分类

  • 针对八种基本数据类型有相应的引用类型—包装类,有了类的特点,就可以调用类中的方法
基本数据类型包装类
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
  • 高亮部分的包装类父类都是:Number
  1. 8中包装类的继承关系图

  • Byte、Short、Integer、Long、Float和Double都是Number的子类,且都实现了Comparable接口。
  • Boolean、Character这两个是单独的类,都实现了Serializable和Comparable接口。

2.2.装箱和拆箱

  • 装箱:基本类型→包装类型,反之即为拆箱
  • jdk5以前是手动装箱和拆箱(以 int 和 Integer 为例)
//jdk5以前是手动装箱和拆箱

//手动装箱 以 int → Integer 为例

int n1 = 100;

Integer integer = new Integer(n1);

Integer integer1 = Integer.valueOf(n1);

//手动拆箱

int n2 = integer.intValue();

System.out.println("integer = "+ integer);

System.out.println("integer1 = "+ integer1);

System.out.println("n2 = "+ n2);

  1. jdk5以后是自动装箱拆箱(以int 和 integer 为例)
//jdk5以后是自动装箱和拆箱

//自动装箱

int n3 = 200;

Integer integer = n3;

//自动拆箱

int n4 = integer;

System.out.println("n3 = "+ n3);

System.out.println("ineger = "+ integer);

  • 通过debug可以看到,自动装箱在底层仍然使用的是 Integer.valueOf() 方法

  • 自动拆箱在底层仍然使用的是 .intValue() 方法

  • 八种类型都可以同样地装箱和拆箱

2.3.包装类和String类的相互转换

  • 包装类以Integer为例,其他类似
//包装类(Integer)→ String

Integer i = 100;//自动装箱

//方式1

String s1 = i + "";

//方式2

String s2 = i.toString();

//方式3

String s3 = String.valueOf(i);

System.out.println("s1 = "+ s1);

System.out.println("s2 = "+ s2);

System.out.println("s3 = "+ s3);

//String → 包装类(Integer)

//方式1

Integer n1 = Integer.valueOf(s3);

//方式2

Integer n2 = new Integer(s3);

System.out.println("n1 = "+ n1);

System.out.println("n2 = "+ n2);

2.4.Integer缓存

  • Integer内部定义了IntegerCache结构,其中定义了数组Integer[],缓存了-128~127范围的整数,在自动装箱时此范围内的整数可以直接使用数组内的元素,不再new新的对象。这种方法可以提高效率。
Integer int1 = 127;

Integer int2 = 127;

System.out.println(int1 == int2);//输出true



Integer int3 = 128;

Integer int4 = 128;

System.out.println(int3 == int4);//输出false

3.基本数据类型、包装类与String类的相互转换