JAVA - 基本数据类型
Java中的基本数据类型
1、Java中的基本数据类型
整形类型: byte , short , int , long
浮点类型:float , double
布尔类型: true , false
字符类型: char
2、基本类型的长度&默认值
数据类型 | 大小 | 范围 | 默认值 | 封装类 |
byte (字节) | 8 | -128 - 127 | 0 | Byte |
shot (短整型) | 16 | -32768 - 32768 | 0 | Short |
int (整型) | 32 | -2147483648-2147483648 | 0 | Integer |
long (长整型) | 64 | -9233372036854477808 - 9233372036854477808 | 0 | Long |
float (浮点型) | 32 | -3.40292347E+38 - 3.40292347E+38 | 0.0f | Float |
double (双精度) | 64 | -1.79769313486231570E+308 - 1.79769313486231570E+308 | 0.0d | Double |
char (字符型) | 16 | ‘ \u0000 - u\ffff ’ | ‘\u0000 ’ | Character |
boolean (布尔型) | 1 | true/false | false | Boolean |
3、封装类表
整形类型&封装类:
byte ---------> Byte
short ---------> Short
int ---------> Integer
long ---------> Long
浮点类型&封装类
float ---------> Float
double ---------> Double
字符类型&封装类
char ---------> Character
布尔类型&封装类
boolean ---------> Boolean
4、基本数据类型间的转换
1、低级别 ------> 高级别
个人理解:
其实低级别就相当于较小的一个容器 A(容积: 0 ~ 10ml);高级别则为大一点的容器B(容积: 0 ~ 1000ml),由于两个容积不同 (A < B),所以我们在使用场景有所不同,容器A可以作为试管,而容器B可以作为喝水的杯子。
举例 1:byte ---> int
输出:public class Test { public static void main(String[] args) { byte b = 12; //小容器 int i = b; //小容器--->大容器 System.out.println(b); System.out.println(i); System.out.println(i==b); } }
12
12
true举例 2:char ---> short
注:char 虽然表现为字符,但是在数值转换中它将表现为Ascll码值, 比如 'a' 的 ASCLL码为97。
输出:public class Test { public static void main(String[] args) { char a = 'a'; char b = 'b'; int ia = a; int ib = b; System.out.println("ia = " + ia); System.out.println("ib = " + ib); } }
ia = 97
ib = 98
2、同级别
同级别的转换,主要涉及三种,在此只总结第一种,浮点与整型之间转换将会在后面总结。
1. char <----------> short
2. int <----------> float (后面总结)
3. long <----------> double(后面总结)
个人理解:
在上面的一张图片中,我们能够发现char 和 short的取值范围并非相同,只有一部分交集,所以如果直接相互转换必定会出现错误,在Java中可以通过强转来完成,当然也是存在一定的风险,比如:将char c = 65535 直接转换给 short s = c 时,虽然我们可以如下面代码编译通过,但是因为short的最大取值为 32767 ,已经超出了short的取值范围,在程序运行时必定出错。所以当我们使用数值转换时定要小心。最终建议:尽量不要使用转换类型,后面将会总结DigDecimal类的操作以解决此类问题。
输出:public class Test { public static void main(String[] args) { char c = 65535; short s = (short) c;<strong>//需要强转</strong> System.out.println(c); System.out.println(s); } }
?
-1
3、高级别 ------> 低级别(强转)
对于高级别向低级别的转换则涉及的名词就是“强转”,也是存在一定的风险。
主要表现为两种:
1、转换错误
2、丢失精度
一、整型类型间的强转
举例 1:int ---> char 【转换错误】
public class Test { public static void main(String[] args) { int i = 65536;//Character.MAX_VALUE + 1 char s = (char) i;<strong>//需要强转</strong> System.out.println("i = "+i); System.out.println("s = "+(int)s); } }
输出:
i = 65536
s = 0
二、浮点类型间的强转
举例 1:double ---> float 【丢失精度】
输出:public class Test { public static void main(String[] args) { double d = Float.MAX_VALUE + 1; float f = (float) d;<strong>//需要强转</strong> System.out.println("d = " + d); System.out.println("f = " + f); } }
d = 3.4028234663852886E38
f = 3.4028235E38
三、整型类型&浮点类型之间的强转
举例 1:float --->int【丢失精度】 | 【转换错误】 | 【转换错误】&【丢失精度】
下面的例子属于最严重的错误类型:【转换错误】&【丢失精度】
输出:public class Test { public static void main(String[] args) { float f = Float.MAX_VALUE; int i = (int) f; System.out.println("f = " + f); System.out.println("i = " + i); } }
f = 3.4028235E38
i = 2147483647总结:
强制类型转换的风险很大,可能有一些取值范围存在交集部分转换正常,而非交集部分则差之千里。这最容易出现“偶现问题”,难于定位。在使用时一定要熟悉转换的取值范围。
5、Java中的装箱与拆箱
前面已经列出了各种基本类型对应的封装类,那么封装类将基本类型对象化的意义在于,开发者更容易操作基本类型,包括以下基本类型下的常量(Max Min)等,下面我们一Integer为例,总结一下封装。
下图1为Integer类的源码中的部分常量&方法
1、MIN_VALUE常量的定义 :可以让我们更加容易取得int类型的最小值
2、toXXXString的定义:可以让开发者更容易的将int转为X进制的字符串
3、与2相反,能够将字符串解析成int,如果不在范围内则抛出NumberFormatException异常
下图为各种封装类的设计:
1、 final 表示此类不允许继承再次封装
2、Comparable 表示此类型可以进行比较并对此类对象集合进行排序
3、Number表示所有的封装类均继承了Number抽象类并实现部分所需的方法,且Number类实现了java.io.Serializable 接口,可以序列化
封装类的装箱:
举例 1:
public class Test { public static void main(String[] args) { Integer I = new Integer(100);//装箱 【基本类型---->封装类】 int ii = I;//拆箱 【封装类---->基本类型】 System.out.println(I); System.out.println(ii); } }
输出:
100
100
封装类的比较:
举例 1:
public class Test { public static void main(String[] args) { Integer I1 = 100;// 装箱 Integer I2 = 100;// 装箱 Integer I3 = 200;// 装箱 Integer I4 = 200;// 装箱 System.out.println(I1 == I2); System.out.println(I3 == I4); } }
输出:
true
false
解释:
为什么同样的装箱操作后,结果却不一样?我们看一下下面的代码就弄明白了,在Integer中有一个缓存机制对于-128 ~127的封装类在装箱时直接获取的是缓存中的Integer对象,对于100当然获取的就是同一个对象了,所以使用==比较了内存的地址,故返回true,而200 超出了缓存大小需要new 重新开辟内存,所以返回false。
最终总结:对于封装类属于引用用类型,在比较时使用equal才是正确的!!!