先说明两个词汇的基本概念:
- bit (位):位是计算机中存储数据的最小单位,指二进制数中的一个位数,其值为“0”或“1”。
- byte (字节):字节是计算机存储容量的基本单位,一个字节由8位二进制数组成。在计算机内部,一个字节可以表示一个数据或者一个英文字母,但是一个汉字需要两个字节表示。
- 1B=8bit
- 1Byte=8bit
- 1KB=1024Byte(字节)=8*1024bit
- 1MB=1024KB
- 1GB=1024MB
- 1TB=1024GB
1、Java 的基本数据类型关系图
2、八种基本数据类型
数据类型 | 字节长度 | 大小/位 | 范围 | 默认值 | 包装类 |
byte(位) | 1 | 8 | [-128~127] | 0 | Byte |
short(短整数) | 2 | 16 | [-32768~32767] | 0 | Short |
int(整数) | 4 | 32 |
[-2147483648~2147483647] (-231~231-1) |
0 | Integer |
long(长整数) | 8 | 64 |
[-9223372036854775808~9223372036854775807] (-263~263-1) |
0L或0l | Long |
float(单精度) | 4 | 32 | 32为IEEE754单精度范围 | 0.0F或0.0f | Float |
double(双精度) | 8 | 64 | 64位IEEE754单精度范围 | 0.0 | Double |
char(字符) | 2 | 16 | Unicode[0~65535] | 空('u0000') | Character |
boolean | 1 | 8 | true和false | flase | Boolean |
3、数据类型之间的转换
1)简单类型数据间的转换,有两种方式:自动转换和强制转换,通常发生在表达式中或方法的参数传递时。
隐式类型转换(自动转换)
当将占位数少的类型赋值给占位数多的类型时,java自动使用隐式类型转换(如int型转为long型)
具体地讲,当一个较"小"数据与一个较"大"的数据一起运算时,系统将自动将"小"数据转换成"大"数据,再进行运算。而在方法调用时,实际参数较"小",而被调用的方法的形式参数数据又较"大"时(若有匹配的,当然会直接调用匹配的方法),系统也将自动将"小"数据转换成"大"数据,再进行方法的调用,自然,对于多个同名的重载方法,会转换成最"接近"的"大"数据并进行调用。这些类型由"小"到"大"分别为
(byte,short,char)→int→long→float→double。
这里我们所说的"大"与"小",并不是指占用字节的多少,而是指表示值的范围的大小。
①下面的语句可以在Java中直接通过:
byte b;int i=b; long l=b; float f=b; double d=b;
②如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值,例如
char c='c'; int i=c; System.out.println("output:"+i);
输出:output:99;
③对于byte,short,char三种类型而言,他们是平级的,因此不能相互自动转换,可以使用下述的强制类型转换。
short i=99 ; char c=(char)i; System.out.println("output:"+c);
输出:output:c;
显式类型转换(强制转换)
当把在级别高的变量的值赋给级别低变量时,必须使用显式类型转换运算(如double型转为float型),强制转换会丢失精度。
2)表达式的数据类型自动提升, 关于类型的自动提升,注意下面的规则。
①所有的byte,short,char型的值将被提升为int型;
②如果有一个操作数是long型,计算结果是long型;
③如果有一个操作数是float型,计算结果是float型;
④如果有一个操作数是double型,计算结果是double型;
例, byte b; b=3; b=(byte)(b*3);//必须声明byte。
3)包装类过渡类型转换
一般情况下,我们首先声明一个变量,然后生成一个对应的包装类,就可以利用包装类的各种方法进行类型转换了。例如:
①当希望把float型转换为double型时:
float f1=100.00f;
Float F1=new Float(f1);
double d1=F1.doubleValue();//F1.doubleValue()为Float类的返回double值型的方法
②当希望把double型转换为int型时:
double d1=100.00;
Double D1=new Double(d1);
int i1=D1.intValue();
简单类型的变量转换为相应的包装类,可以利用包装类的构造函数。即:Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value)
而在各个包装类中,总有形为××Value()的方法,来得到其对应的简单类型数据。利用这种方法,也可以实现不同数值型变量间的转换,例如,对于一个双精度实型类,intValue()可以得到其对应的整型变量,而doubleValue()可以得到其对应的双精度实型变量。
4)字符串与其它类型间的转换
其它类型向字符串的转换
①调用类的串转换方法:X.toString();
②自动转换:X+"";
③使用String的方法:String.volueOf(X);
字符串作为值,向其它类型的转换
①先转换成相应的封装器实例,再调用对应的方法转换成其它类型
例如,字符中"32.1"转换double型的值的格式为:new Float("32.1").doubleValue()。也可以用:Double.valueOf("32.1").doubleValue()
②静态parseXXX方法
String s = "1";
byte b = Byte.parseByte( s );
short t = Short.parseShort( s );
int i = Integer.parseInt( s );
long l = Long.parseLong( s );
Float f = Float.parseFloat( s );
Double d = Double.parseDouble( s );
③Character的getNumericValue(char ch)方法
5)Date类与其它数据类型的相互转换
整型和Date类之间并不存在直接的对应关系,只是你可以使用int型为分别表示年、月、日、时、分、秒,这样就在两者之间建立了一个对应关系,在作这种转换时,你可以使用Date类构造函数的三种形式:
①Date(int year, int month, int date):以int型表示年、月、日
②Date(int year, int month, int date, int hrs, int min):以int型表示年、月、日、时、分
③Date(int year, int month, int date, int hrs, int min, int sec):以int型表示年、月、日、时、分、秒
在长整型和Date类之间有一个很有趣的对应关系,就是将一个时间表示为距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数。对于这种对应关系,Date类也有其相应的构造函数:Date(long date)。
获取Date类中的年、月、日、时、分、秒以及星期你可以使用Date类的getYear()、getMonth()、getDate()、getHours()、getMinutes()、getSeconds()、getDay()方法,你也可以将其理解为将Date类转换成int。
而Date类的getTime()方法可以得到我们前面所说的一个时间对应的长整型数,与包装类一样,Date类也有一个toString()方法可以将其转换为String类。
4、总结
只有boolean不参与数据类型的转换
(1)自动类型的转换:
a.常数在表数范围内是能够自动类型转换的
b.数据范围小的能够自动数据类型大的转换(注意特例)
int到float,long到float,long到double 是不会自动转换的,不然将会丢失精度
c.引用类型能够自动转换为父类的
d.基本类型和它们包装类型是能够互相转换的
(2)强制类型转换:用圆括号括起来目标类型,置于变量前
代码示例:
1 byte i = 12; 2 System.out.println("byte:"+i); 3 short i2 = i; 4 System.out.println("short:"+i2); 5 int i3 = i; 6 System.out.println("int:"+i3); 7 long i4 = i; 8 System.out.println("long:"+i4); 9 float i5 = i; 10 System.out.println("float:"+i5); 11 double i6 = i; 12 System.out.println("double:"+i6); 13 14 15 char j = '²'; 16 System.out.println("char:"+j); 17 int j3 = j; 18 System.out.println("int:"+j3); 19 long j4 = j; 20 System.out.println("long:"+j4); 21 float j5 = j; 22 System.out.println("float:"+j5); 23 double j6 = j; 24 System.out.println("double:"+j6);
输出:
byte:12 short:12 int:12 long:12 float:12.0 double:12.0 char:² int:178 long:178 float:178.0 double:178.0
从右向左均要进行强制类型转换,才能通过编译。强制转换会丢失精度
1 double i = 178.33; 2 System.out.println("double:"+i); 3 float i1 = (float) i; 4 System.out.println("float:"+i1); 5 long i2 = (long) i; 6 System.out.println("long:"+i2); 7 int i3 = (int) i; 8 System.out.println("int:"+i3); 9 short i4 = (short) i; 10 System.out.println("short:"+i4); 11 byte i5 = (byte) i; 12 System.out.println("byte:"+i5); 13 char i6 = (char) i; 14 System.out.println("char:"+i6);
输出:
double:178.33 float:178.33 long:178 int:178 short:178 byte:-78 char:²
5、Java引用类型
Java有 5种引用类型(对象类型):类 接口 数组 枚举 标注
引用类型:底层结构和基本类型差别较大
JVM的内存空间:
(1)Heap 堆空间:分配对象 new Student()
(2)Stack 栈空间:临时变量 Student stu
(3)Code 代码区 :类的定义,静态资源 Student.class
eg:Student stu = new Student(); //new 在内存的堆空间创建对象
stu.study(); //把对象的地址赋给stu引用变量
上例实现步骤:
a.JVM加载Student.class 到Code区
b.new Student()在堆空间分配空间并创建一个Student实例;
c.将此实例的地址赋值给引用stu,栈空间;
6、单精度和双精度单区别?
单精度数是指计算机表达实数近似值的一种方式。单精度,也就是 float ,在 32 位机器上用 4 个字节来存储的;而双精度double是用 8 个字节来存储的,这是他们最本质的区别。
7、String是最基本的数据类型吗?
不是。
基本数据类型包括byte、int、char、long、float、double、boolean和short。
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类。
java 中String 是个对象,是引用类型 ,基础类型与引用类型的区别是,基础类型只表示简单的字符或数字,引用类型可以是任何复杂的数据结构 ,基本类型仅表示简单的数据类型,引用类型可以表示复杂的数据类型,还可以操作这种数据类型的行为 。
java虚拟机处理基础类型与引用类型的方式是不一样的,对于基本类型,java虚拟机会为其分配数据类型实际占用的内存空间,而对于引用类型变量,他仅仅是一个指向堆区中某个实例的指针。
参考: