基本数据类型
在Java中,数据类型一共分为两大类:基本数据类型、引用数据类型。由于引用数据类型较难理解,所以在此先介绍基本数据类型。
基本数据类型由Java语言定义,不可以再进行划分。基本数据类型的数据占用内存的大小固定,在内存中存入的是数值本身,而引用数据类型在内存中存入的是引用数据的存放地址,并不是数据本身。
基本数据类型是一个单纯的数据类型,它表示的是一个具体数字、字符或逻辑值。
在Java中规定了8种基本数据类型来存储整数、浮点数、字符和布尔值,如下图所示:
一个变量就如同一个杯子或一个容器,在期内要装载某个特定的数值(如同杯子可以盛水)。杯子有大有小,盛的水也有多有少。同样,不同类型的变量,其能表示的数据范围也是不同的。
Java基本数据类型占用内存位数及可表示的数据范围如下表所示:
1、整数类型(Integer)
定义:整数类型,简称整型,表示的是不带有小数点的数字。例如:10,20等。
分类:byte类型、short类型、int类型、long类型,默认情况下为int类型。可以以二进制、八进制、十进制和十六进制表示。
(1)byte类型
在Java中,byte类型占据1字节内(8个bit)存空间,取值范围为-128(-27) ~ 127(27-1),下面让我们来看看byte的具体使用方法:
public class ByteDemo {
public static void main(String[] args) {
byte byteMax = Byte.MAX_VALUE; // 获取byte类型最大值
System.out.println("byte类型最大值:" + byteMax);
byte byteMin = Byte.MIN_VALUE; // 获取byte类型最小值
System.out.println("byte类型最小值:" + byteMin);
byte byteSize = Byte.SIZE; // 获取byte类型大小
System.out.println("byte类型大小:" + byteSize);
byte b = 20; // 定义一个byte类型数据
System.out.println("b的值是:" + b);
}
}
【结果】
在上面的例子中,变量b的值是20,在byte类型的取值范围(-128 ~ 127)内,但如果不在这个范围内呢?
public class ByteDemo {
public static void main(String[] args) {
byte b = 128; // 定义一个byte类型数据
System.out.println("b的值是:" + b);
}
}
【结果】
可以看出,128超出了byte类型的取值范围。
解决方法就是扩充数据操作范围:可以将byte扩充为范围比它更大的short、int或long。即重新将变量b声明成short、int或long类型。
(2)short类型
在Java中,short类型占据2字节内(16个bit)存空间,取值范围为-32768(-215) ~ 32767(215-1),short的具体用法与byte基本相同,这里不再赘述。
(3)int类型
在Java中,int类型占据4字节内(32个bit)存空间,取值范围为-231 ~ 231-1,下面具体看一下int类型的用法:
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 获取int类型最大值
System.out.println("int类型最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 获取int类型最小值
System.out.println("int类型最小值:" + intMin);
int intSize = Integer.SIZE; // 获取int类型大小
System.out.println("int类型大小:" + intSize);
int i = 127; // 定义一个int类型数据
System.out.println("i的值是:" + i);
}
}
【结果】
下面再看一个有趣的例子:
public class IntDemo {
public static void main(String[] args) {
byte b1 = Byte.MAX_VALUE + 1; // byte类型最大值加1
byte b2 = Byte.MIN_VALUE - 1; // byte类型最小值减1
short s1 = Short.MAX_VALUE + 1; // short类型最大值加1
short s2 = Short.MIN_VALUE - 1; // short类型最小值减1
System.out.println(b1);
System.out.println(b2);
System.out.println(s1);
System.out.println(s2);
}
}
【结果】
可以看出,结果全部超出取值范围。
解决方法同样是扩充数据操作范围:可以将byte或short扩充为范围比它更大的int或long。
那么int类型又怎么样呢?
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 获取int类型最大值
System.out.println("int类型最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 获取int类型最小值
System.out.println("int类型最小值:" + intMin);
int i1 = Integer.MAX_VALUE + 1; // int类型最大值加1
System.out.println("int类型最大值加1是:" + i1);
int i2 = Integer.MIN_VALUE - 1; // int类型最大值加1
System.out.println("int类型最小值减1是:" + i2);
}
}
【结果】
可以看出,int类型最大值加1结果不会溢出,只是变成了最小值;最小值减1,结果会变成最大值。
以下是二进制表示:
package data_type;
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 获取int类型最大值
System.out.println("int类型最大值二进制: " + Integer.toBinaryString(intMax));
int intMin = Integer.MIN_VALUE; // 获取int类型最小值
System.out.println("int类型最小值二进制: " + Integer.toBinaryString(intMin));
int i1 = Integer.MAX_VALUE + 1; // int类型最大值加1
System.out.println("int类型最大值+1二进制: " + Integer.toBinaryString(i1));
int i2 = Integer.MIN_VALUE - 1; // int类型最大值加1
System.out.println("int类型最小值-1二进制: " + Integer.toBinaryString(i2));
}
}
【结果】
数据最大值、最小值会出现一个循环过程,这种情况称为数据溢出(overflow)。
而解决溢出的方法就是扩大数据的操作范围,将int扩充为long类型。
public class IntDemo {
public static void main(String[] args) {
int intMax = Integer.MAX_VALUE; // 获取int类型最大值
System.out.println("int类型最大值:" + intMax);
int intMin = Integer.MIN_VALUE; // 获取int类型最小值
System.out.println("int类型最小值:" + intMin);
int i1 = Integer.MAX_VALUE + 1; // int类型最大值加1
System.out.println("int类型最大值加1是:" + i1);
int i3 = Integer.MAX_VALUE + 2; // int类型最大值加2
System.out.println("int类型最大值加2是:" + i3);
int i2 = Integer.MIN_VALUE - 1; // int类型最大值加1
System.out.println("int类型最小值减1是:" + i2);
int i4 = Integer.MIN_VALUE - 2; // int类型最大值加2
System.out.println("int类型最大值减2是:" + i4);
}
}
【结果】
(4)long类型
在Java中,long类型占据4字节内(64个bit)存空间,取值范围为-263 ~ 263-1,下面具体看一下long类型的用法:
注:为一个long类型的变量赋值时需要注意一点,所赋值的后面要加上一个“L”或“l”,说明赋值为long类型。但如果赋的值未超出int型的取值范围,则可省略“L”或“l”。
public class LongDemo {
public static void main(String[] args) {
long longMax = Long.MAX_VALUE; // 获取long类型最大值
System.out.println("long类型最大值:" + longMax);
long longMin = Long.MIN_VALUE; // 获取long类型最小值
System.out.println("long类型最小值:" + longMin);
long longSize = Long.SIZE; // 获取long类型大小
System.out.println("long类型大小:" + longSize);
long l1 = Long.MAX_VALUE + 1; // long类型最大值加1
System.out.println("long类型最大值加1是:" + l1);
long l3 = Long.MAX_VALUE + 2; // long类型最大值加2
System.out.println("long类型最大值加2是:" + l3);
long l2 = Long.MIN_VALUE - 1; // long类型最大值加1
System.out.println("long类型最小值减1是:" + l2);
long l4 = Long.MIN_VALUE - 2; // long类型最大值加2
System.out.println("long类型最大值减2是:" + l4);
}
}
【结果】
可以看出,long和int类型一样结果产生溢出。
2、浮点类型
定义:浮点型数据主要用来表示的是带有小数点的数字。例如:10.3,20.02等。
分类:float类型(单精度)、double类型(双精度)。
(1)float类型
在Java中,float类型占据4字节内存空间,共32个bit,第1位为符号位,中间8位表示指数,最后23位表示尾数。
下面我们来看下float类型的使用:
public class FloatDemo {
public static void main(String[] args) {
float f = 3.0f;
System.out.println(f + " * " + f + " = " + f*f);
}
}
【结果】
注:含小数的实数默认为double类型数据,如果定义的是float型数据,为其赋值时必须要执行强制转换,方法如下
// 1、直接在数字后加上“f”或“F”
float f1 = 3.0f;
// 2、直接在数字前面加强制转换
float f2 = (float)1.2;
(2)double类型
在Java中,double类型占据8字节内存空间,共64个bit。
下面我们来看下double类型的使用:
public class DoubleDemo {
public static void main(String[] args) {
float fMax = Float.MAX_VALUE;
float fMin = Float.MIN_VALUE;
double dMax = Double.MAX_VALUE;
double dMin = Double.MIN_VALUE;
System.out.println("float类型最大值:" + fMax);
System.out.println("float类型最小值:" + fMin);
System.out.println("double类型最大值:" + dMax);
System.out.println("double类型最小值:" + dMin);
}
}
【结果】
float f = 2.456e67; // 错误,超出float可表示范围
double d1 = 1.8e308; // 错误,超出double可表示范围
2、字符类型(Char)
定义:即字母和符号的统称。
字符类型在内存中占有2个字节,8个bit。使用方法如下:
public class CharDemo {
public static void main(String[] args) {
char c1 = 'a'; // 可以是字母
char c2 = '中'; // 可以是汉字
char c3 = 97; // 可以是数字,ASCII码中97对应字母'a'
int i = 'a'; // char转int
System.out.println(c1 + "\n" + c2 + "\n" + c3 + "\n" + i);
}
}
【结果】
注1:字符要用一对单引号(’’)括起。
注2:Java之中默认采用的编码方式是Unicode编码,此编码是一种采用十六进制编码方案,可以表示出世界上任意的文字信息。所以,在Java中,单个字符里面是可以保存中文字符的。而在C/C++中,中文字符只能当作字符串处理。
注3:char和int型数据的互相转换问题,遵循C语言常用的ASCII码习惯,大写字母A ~ Z 对应65 ~ 90、小写字母a ~ z对应整数97 ~ 122、字符0 ~ 9对应49 ~57。
3、布尔类型(boolean)
在Java中使用关键字boolean来声明布尔类型。被声明为布尔类型的变量,只有true(真)和false(假)两种。除此之外,没有其他的值可以赋值给这个变量。
public class BoolDemo {
public static void main(String[] args) {
boolean bool = true;
if(bool)
System.out.println("I love Java!");
}
}
基本数据类型的默认值
在Java中,若在变量的声明时没有赋初值,则会给该变量赋默认值。下表列出了各种类型的默认值。
基本数据类型的转换
1、自动类型转换
自动转换条件
(1)转换前后的数据类型要相互兼容。
(2)转换后的数据类型的表示范围小于转换前的类型。即扩大转换。
注1:Java中,由于boolean类型只能存放true或false,与数字及字符不兼容,因此,boolean类型不能与其他任何数据类型进行转换。
注2:Java在进行数值运算时,以尽量不损失精度(正确性)为准则。
例如:一个字符型变量(本质上是2Byte大小的整数)与一个整型变量(默认4Byte大小的整数)进行运算,在运算前,不同类型的操作数需要先转化成同一数据类型,然后再运算。因此,要先将字符型的变量转换为整型变量,否则将4字节整型变量转换为2字节的字符型,很有可能导致整型变量的值会溢出,从而导致计算错误。字符与整数是可使用自动类型转换的。
假设参与某种运算有两个不同的操作数(操作数1和操作数2),二者具有不同的数据类型,在运算操作之前,它们需要转换为同一数据类型,其相互转换的规则如下表所示。
下面看个例子:当两个数中有一个为浮点数时,其运算的结果会有什么样的变化。
public class Demo {
public static void main(String[] args) {
int a = 152;
float b = 24.1f;
System.out.println("a = " + a + "\n" + "b = " + b);
System.out.println("a/b = " + a/b);
}
}
【结果】
【结果分析】
从运行的结果可以看出,当两个数中有一个为浮点数时,其运算的结果会直接转换为浮点数。
当表达式中变量的类型不同时,Java会自动把较小的表示范围转换成较大的表示范围后,再做运算。也就是说,假设有一个整数和双精度浮点数作运算,Java会把整数转换成双精度浮点数后再做运算,运算结果也会变成双精度浮点数。
2、强制类型转换
【语法】
(欲转换的数据类型)变量名;
【例】
public class DefaultDemo {
public static void main(String[] args) {
int a = 152, b = 9;
float f1, f2, f3, f4;
System.out.println("a = " + a + "\n" + "b = " + b);
f1 = a/b;
f2 = (float)a/b; // 将整数a强制转换为浮点数,再与b相除
f3 = a/(float)b; // 将整数b强制转换为浮点数,再以a除之
f4 = (float)a/(float)b; // 将整数a,b同时强制转换为浮点数,再相除
System.out.println("f1 = a/b = " + f1);
System.out.println("f2 = (float)a/b = " + f2);
System.out.println("f3 = a/(float)b = " + f3);
System.out.println("f4 = (float)a/(float)b = " + f4);
}
}
【结果】
【结果分析】
当两个整数相除时,小数点后的数字会被截断(并不四舍五入),使得运算结果为整数。要想得到浮点数,必须将其中一个或两个数转换为浮点数。
注:若将一个超出该变量可表示范围的值赋给这个变量,这种转换称为缩小转换。由于在转换的过程中可能会丢失数据的精确度,因此Java并不会“自动”做这些类型的转换,此时就必须要做强制性的转换,例如 int x = (int)10.35(结果x=10),将double类型的值(10.35)强制转换为int类型(10),这样也丢失了很多的信息。