1.java的基本数据类型(八种)与引用数据类型(三种)
一:java中数据类型分为两大数据类型:
1基本数据类型;2引用数据类型
1:java开发过程中整型用int、小数用double、布尔用boolean;
2:类型转换都是小范围向大范围转换,大范围往小范围转化需要用到强制转换;
例如:(1)int a=12;double b=a;(2)double a=3.0;int b=(int)a;
3:long,byte,char等很少用到,一般在数据处理的时候会用到;
4:int跟char之间的转换是通过ASCII转化的;
例如:char a ='A';int b=a;System.out.prientln(b);最后输出的结果为65;
5:String类型,String是项目中必不可少且使用最多的数据类型,它属于引用数据类型中“类”的范畴。
int 和 Integer 有什么区别
Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
原始类型对应的包装类型:
原始类型 | boolean、byte、short、long、float、double | char | int |
包装类型 | 首字母大写 |
封装类为各个数据类型提供一些数据的操作方法,可以直接使用;
Integer a= 127 与 Integer b = 127相等吗
对于对象引用类型:==比较的是对象的内存地址。
对于基本数据类型:==比较的是值。
如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false:
例如String跟int的互相转化:
String a = "21";int b = Integer.parseInt(a);//String 转int。
int a = 21; String b = String.valueOf(a);//int转String。
byte、char、short、int、long的长度
一个字节长度是8位,即可以理解为下标为(0-7),只作参考。2个字节(0-15),4个字节(0-31)
引用数据类型:数组、类、接口
java基本数据类型:
名称 | 数据类型 | 字节数 | 比特数 | 可表示数 | 范围 | 备注 | 封装类型 | |
整数类型 | 字节型 | byte | 1 | 8 | 2^8 | -2^4~2^4-1 | -2^7 ~ (2^7)-1 | |
短整型 | short | 2 | 16 | 2^16 | -2^8~2^8-1 | -2^15 ~ (2^15)-1 | ||
整型 | int | 4 | 32 | 2^32 | -2^16~2^16-1 | -2^31 ~ (2^31)-1 | ||
长整型 | long | 8 | 64 | 2^64 | -2^32~2^32-1 | -2^63 ~ (2^63)-1 | ||
浮点类型 | 浮点型 | float | 4 | 32 | ||||
双精度浮点型 | double | 8 | 64 | |||||
布尔型 | boolean | 1 | 8 | true、false | ||||
字符类型 | 字符型 | char | 2 | 16 | -2^7 ~ (2^7)-1 | Character |
关于float和double的区别:
总共占用比特位数(32bits和64bits) | 尾数 | 取值范围 | 有效数字位数 | 定义方法 | 备注 | |||
数符(1bit) | 指数位(小数点的位置) | |||||||
指数符 | 指数 | |||||||
float(单精度浮点数) | 1bit表示正负 | 8bits | 23bits | -2^128~2^128-1 | 7位(2^23是7位十进制数)8? | float a=0.1f(或F) | 容易损失精度,开发过程不常用 | |
1bit | 7bits | |||||||
"."后边的数字 | -3.40E38~3.40E38 | |||||||
double(双精度浮点数) | 1bit表示正负 | 11bits | 52bits | -2^1024~2^1024-1 | 16位(2^52是16位十进制数)17? | double b=0.1 | 开发过程中常用 | |
1bit | 10bits | -1.79E308~1.79E308 |
表注:
指数符 :(阶数、移数)表示指数的正负(阶数、移数)表示指数的正负。取值范围(取决于阶数)
指数:(阶数、移数)存指数的有效数字。有效数字位数(取决于尾数)
2.关于数据类型的转换:
先来看一个简单的面试题:short s = s + 1和s += 1的区别。换个说法,为什么short s1 = 1; s1 = s1 + 1;有错,而short s1 = 1; s1 += 1;没有编译错误?
关键字
java, 数据类型, 默认类型,运算符优先级、类型溢出
包括我很多人第一眼看题目中两者在运算上毫无区别。由于我们在平时的编程中很少涉及类型溢出、优先级考虑等问题,数据类型、包装类、又是单目运算符,又是三元运算符等等。
但如果涉及到要考虑性能、考虑存储细节,还是要了解一下这些数据类型转换的。
short s = 1;
s = s+1;
System.out.println(s);
输出:报错
原因:在s + 1的时候,结果会被“升格”为int类型。将int高级类型转为低级类型,需要强制转换,所以自然编译不会通过。对两个容量不一样的数据类型的变量进行算术运算时,java会自动将小容量的变量进行精度提升,然后再进行运算,得到的结果类型是提升后的大容量的数据类型.如果将该结果赋值给小容量的数据类型的变量,则必须进行强制的类型转换,否则编译程序会报损失精度错。
因为short s1=1在栈中开辟了一个short类型的空间;
而s1=s1+1;中s1是short类型,在栈中开辟了一个short类型的空间,而1是int类型,
int类型比short类型大,所以相加后的结果应为比较大的类型,把s1+1的结果赋予short类型的变量s1,固然需要强行转化;
short s = 1;
s += 1;
System.out.println(s);
输出:2
原因:对于“+=”操作,jvm会自动执行类型操作,等价于 s = (short)(s + 1)
由于+=运算符有自加功能,定义short s1 = 1;时,开辟了一个空间,当通过+=运算符运算时,只是在原来的栈中进行运算;不需强行转化。s1+=i的方式java会对i进行窄化转换,由编译程序自动执行。
上面只是浅显一点的原因,再本质的原因,总结如下。
java数据类型
在java中数据类型(byte, short, char) -> int ->long -> float -> double,从左到右低阶到高级,不同数据类型之间既有能表示范围的区别,同时由于java是强类型语言,所以严格按照(当然还有一些封装方法可以相互转换,这里不扩展,只介绍基本类型)以下规则转换:
隐式转换与显式转换:
byte b = 1;
short s =1;
char c =1;
long l = 1;
int i = 1;
float f = 1;
double d = 1.0;
下表中表示各数据类型之间的转换,列标题表示被转换的类型,行标题表示转换成的类型:
byte | short | char | int | long | float | double | |
byte | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 |
short | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 |
char | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 | 强转 |
int | i=b+1 | i=s+1 | i=c+1 | i=i+1 | 强转 | 强转 | 强转 |
long | l=b+1 | l=s+1 | l=c+1 | l=i+1 | l=l+1 | 强转 | 强转 |
float | f=b+1 | f=s+1 | f=c+1 | f=i+1 | f=l+1 | f=f+1 | 强转 |
double | d=b+1 | d=s+1 | d=c+1 | d=i+1 | d=l+1 | d=f+1 | d=d+1 |
自动转换:
低阶变量可以直接转换为高级变量:
byte、short、char、int、long、float、double从左到右精度依次升高。
上表中所有可以用等号直接转的,都是自动转换。
显式转换:
从高级变量转为低级变量,需要使用强制转换,比如short s=1,s=(short)(s+1) ,但是要注意转换后可能丢失精度或者数据溢出。
java的默认类型
在java中,整数默认是 int 类型,小数默认是 double 类型 ;因此,在一些地方会造成一些错误,除了上面s + 1中的“1”编译器默认为int类型之外,还有诸如:
long num = 99999999999999; // error
编译器也是会报错的!原因是编译器把99999999999999当成int类型,然而99999999999999超出了int能表示的范围,所以改成如下就好了:
long num = 99999999999999L; // ok
运算符优先级
总结:赋值运算符“=”优先级最低,而“+=”运算符比较高,在解析s += 1的时候由于是“+=”操作符,编译器解析时先将其转换为 s = (short)(s + 1),更深层次涉及到jvm如何实现。
java规范中说:
E1 op=E2 实际上等价于 : E1=(T)( (E1)op(E2) )
其中T是E1的数据类型.这种类型转换或者是一个恒等转换,或者是一个窄化转换.
这个说明java是一种强类型的语言,对数据类型的要求是非常严格的,否则会引起混乱.
下面解释一下三种类型转换:恒等转换(相同容量的两个数据类型之间的赋值);拓宽转换(小容量类型赋值给大容量类型);窄化转换(大容量赋值给小容量类型). 实际上,前两种转换都是编译程序自动执行的,而窄化转换则要求必须显式的执行。