基本数据类型和类型转换

基本数据类型介绍

Java 的基本数据类型共有 8 种,分为两类:boolean 类型和数值类型,数值类型又可以分为整数类型、字符类型、浮点类型。

基本数据类型和类型转换

整数类型

  • byte:1个字节,范围:(-2^7) ~ (2^7-1)
  • short:2个字节,范围:(-2^15) ~ (2^15-1)
  • int:4个字节,范围:(-2^31) ~ (2^31-1)
  • long:8个字节,范围:(-2^63) ~ (2^63-1)

int 是最常用类型,通常情况下,直接给出一个整数值默认就是 int 类型,例如:

//128会被系统默认当成int类型,然后赋值给变量a
int a = 128;   

有两种特殊情况必须指出:

  • 将一个较小的整数值(在 byte 或 short 类型范围内)赋给一个 byte 或 short 变量,系统会自动把将 int 类型转换为 byte 或者 short 类型来处理。
  • 将一个巨大的整数值(超出了 int 类型范围)赋予 long 类型,系统不会自动将它转换为 long 类型来处理,必须在整数值后加 l 或者 L 作为后缀。
//代码正确,系统自动把56转换byte类型
byte a = 56;  

//代码错误,整数值超过int类型范围
long bigValue1 = 99999999999999999; 
//代码正确,在整数值后添加L,强制使用long类型
long bigValue2 = 99999999999999999L;  

注意:将一个整数值(int 类型范围内)赋给 long 类型,编译可以通过,这不是特殊情况,这是自动类型转换。

//99是int类型,赋值时,自动类型转换为long类型
long bigValue3 = 99;  

整数值表示形式:

  • 十进制:平常使用数值
  • 二进制:以 0b 或者 0B 开头
  • 八进制:以 0 开头
  • 十六进制:以 0x 或者 0X 开头,其中 10 ~ 15 以 a ~ f 或者 A ~ F 来表示
//十进制212的各种表示方式
int binVal = 0b11010100;  //二进制
int octalVal = 0324;      //八进制
int hexVal = 0xd4;        //十六进制

注意:二进制或者十六进制表现的是整数在内存中的存储形式(补码),默认的二进制整数值是 32 位,最高位(第 32 位)为符号位。

int binVal = 0B10000000000000000000000000000011;
//-2147483645,最高符号位为第32位,为负数
System.out.println(binVal); 

//整数值默认为int,最高符号为第32位,为正数
byte binVal2 = (byte)0b11101001;  
//-23,强制转换后,最高符号位为第8位,为负数
System.out.println(binVal2);  

//二进制后缀加L,代表整数值为long类型
long binVal3 = 0B10000000000000000000000000000011L; 
//2147483651,最高符号位为第64位,为正数
System.out.println(binVal3); 

字符类型

char 类型是 16 位 Unicode 编码字符,本质上是 16 位无符号整数,可以将 0 ~ (2^16-1) 范围内的 整数值直接赋给 char 类型变量,系统会自动将 int 类型转换为 char 类型。

字符型值表示形式:

  • 单个字符,'A','9' 等
  • 转义字符,' ',' ' 等
  • 使用 Unicode 值,格式为 uXXXX,其中 XXXX 代表一个十六进制整数,范围为 u0000 ~ uFFFF,其中前 256 个(u0000 ~ u00FF)字符和 ASCII 码中的字符完全重合。
char aChar = 'a';       //单个字符
char enterChar = '
';  //转义字符
char ch = 'u9999';     //Unicode编码
char c = 97;            //给char类型变量赋值整数值
int zhongValue = '疯';  //char类型自动转换为int

浮点类型

  • float:4 个字节(32 位),第 1 位是符号位,接下来 8 位是指数,再接下来 23 位是尾数
  • double:8 个字节(64 位),第 1 位是符号位,接下来 11 位是指数,再接下来 52 位是尾数

浮点型表示形式:

  • 十进制:平常使用数值,例如 3.14。必须包含小数点,要不然会被当成 int 类型
  • 科学计数法:例如 3.14e2 或者 3.14E2(即 3.14 * 10^2

double 是最常用类型,通常情况下,直接给出一个浮点数值默认是 double 类型,如果希望当成 float 类型处理,在浮点数值后加 f 或 F。

//代码正确,3.14被系统默认当成double类型,然后赋值给a
double a = 3.14;  
//代码错误,3.14默认为double类型,不能直接赋给float类型
float b = 3.14;  
//代码正确,3.14f为float类型
float c = 3.14f;  

特殊浮点数值:

  • 正无穷大:Double 类或 Float 类的 POSITIVE_INFINITY,正数除以 0
  • 负无穷大:Double 类或 Float 类的 NEGATIVE_INFINITY,负数除以 0
  • 非数:Double 类或 Float 类的 NaN,0.0 除以 0.0 或对一个负数开方
double a = 3.14;
System.out.println(a/0);  //Infinity

int b = 4;
System.out.println(b/0);   //报错

布尔类型

boolean 类型只有 true 和 false 两种类型,不能用 0 或者非 0 代替,其他类型值不能转换为 boolean 类型,这和 C++ 是不同的。Java 没有强制规定 boolean 类型所占内存空间,一般为 8 位。

boolean b1 = true;
boolean b2 = false;

System.out.println(b1 + "-" + b2);  //true-false

基本类型的类型转换

Java 抛开 boolean 类型外的 7 种数值类型可以相互转换,有两种转换方式:自动类型转换和强制类型转换。表达式在计算过程存在操作数的类型自动提升的情况。

自动类型转换

把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量时,系统会进行自动类型转换,无需其他操作。可以想象成有两瓶水,当把小瓶里的水倒入大瓶中时不会有任何问题。

基本数据类型和类型转换

上图中,箭头左边的数组类型可以自动转换右边的数组类型。

byte c = 2;
//byte类型自动转换为double
double d = c;
System.out.println(d);  //2.0


强制类型转换

把一个表数范围小的数值或变量直接赋给另一个表数范围大的变量,需要强制类型转换。转换过程可能会数据丢失,可以想象成把一个大瓶子里的水倒入一个小瓶子,如果大瓶子里的水不多还好,但如果大瓶子里的水很多,将会引起溢出,从而造成数据丢失。

int iValue = 233;
//将int类型强制转换为byte类型
byte bValue = (byte) iValue;
System.out.println(bValue);  //-23

表达式类型的自动提升

当一个算术表达式中包含多个基本类型的值时,整个算术表达式的数据类型将发生以下自动提升:

  • 所有的 byte 类型、short 类型和 char 类型将被提升到 int 类型;
  • 表达式的结果会自动提升到和最高等级的操作数相同的类型。
short sValue = 5;
//错误,sValue是short类型,在表达式中自动提升到int类型,数值2默认是int类型,
//sValue-2整个表达式结果类型为int,不能赋给short类型
sValue = sValue - 2;
short value = 3;
//正确,value被自动提升到int类型,23也是int类型,整个表达式结果为int类型
int initResult = 23/value;
short a = 5;
byte b = 10;
double c = 1.0;
//正确,首先a和b自动提升到int类型,c为double类型
//b/c的结果类型自动提升到为double, a和double类型相加,最终结果也自动提升到double
double d = a + b / c;