文章大纲
1.介绍基本数据类型的相关特点
2.数据类型注意事项
3.相关考题解析
基本数据类型的相关特点
8种基本数据类型一张图概括全部的数据类型,主要的研究的是上面的基本数据类型,下面再以各种数据类型所占字节数大小再重新分类一遍帮助记忆:
基本数据类型所占字节数boolean
布尔类型再强调一遍:只有true和false
byte
1位(是数据的最小单位) ,但是大多数情况下数据最小单位为1个字节(byte)因为1 bit 的信息量太少了。要表示一个有用的信息,需要好几个bit一起表示。我们的其他基本数据类型都是由byte组成。
那么讲到字节就稍微提一下字符编码 ASCII,Unicode和UTF-8之间的概念和由来。
ASCII是上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码,一直沿用至今。它由一个字节组成也就是8位,一共表示128个字符。因为西方的英文就26个字母,再加上大写字母各种其他的符号。128也是够用的了(因为第一位规定为0 所以就只表示128个字符啦)
ASCII字符表但是西方国家还有很多,比如德国法国等,他们的语言也需要一套字符编码,不过都是在一个字节之内就能解决的事情。每个国家就定义了自己的一套标准
其中最常见的ISO/IEC 8859-1就是法语,芬兰语所用的西欧字符集
但是中文就比较复杂,有10万多个汉字,那么这意义着要更多的字节去表示这些汉字
然后同一段字节流到了不同的国家可能因为标准不同,导致会变出各种奇怪的符号,也就是不统一了。
那么最终还是要统一的,就出现了unicode全世界每个不同语言的不同字符都统一编码,全球通行。默认unicode采用2个字节,先讲这么多。不要跑题了。
char
char的基本特点有一道面试题:java中的一个char变量能否表示一个汉字,为什么?
当时我是有点懵逼的,到底可以还是不可以呢?(希望有大神能详细解答一下)
我查了一下正确答案是可以的 unicode是2个字节 (16位)可以表示汉字。
整型常量和浮点型常量
整型常量的范围和占用空间 浮点型常量的范围和占用空间补充一下相关字节和位的知识:
1个字节=8位 8位代表256个数字 第一位符号位 0 正 1负 其余7位代表数字 2^7=127 因为只有一个0
当1 0000000时表示-128 所以 byte为 -128-127 其他类型以此类推
问题1:在不同的位数的操作系统上 是否基本数据类型所表示的范围相同呢?
答:在C/C++上是不同的,但是在java上是相同的。
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节
以上占用字节数其实是针对c/c++语言而言的,对于java来说由于其JVM具有跨平台性因此java在32位和64位机下基本数据类型占字节数是一致的(这样才能达到跨平台通信)。
问题2:
如果是在不同位数的jvm上呢?32位的jvm和64位的jvm是否表示范围相同?
看到这个问题的我,是一脸懵逼的。
个人感觉应该不同吧,毕竟java是跑在jvm上的所以和操作系统的位数没关。那么jvm的位数应该就有关了吧。(希望有大神能解答)
数据类型注意事项
1.自动类型转换
本数据类型中,布尔类型boolean占有一个字节,由于其本身所代码的特殊含义,boolean类型与其他基本类型不能进行类型的转换(既不能进行自动类型的提升,也不能强制类型转换), 否则,将编译出错。
转换图转换图的几点说明:
1.红色的int和double代表,在Java中,整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型(float/double)中,对于未声明数据类型的浮点型,默认为double型。
2.上下两个大的蓝色箭头表示,从低到高类型自动转换,高到低需要强制转换,原因很简单,高位表示的范围大,低位表示的范围小。
3.在byte char short之间的爆炸符号,代表的意思虽然类型从小到大自动转换,但是byte不能转成char,char也不能转成short。因为byte和short是是数值型的变量,char字符型的变量。数值型变量有符号(第一位)而在char中则无正负之分。byte转short自然就是可以的了。
例题引出问题:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
long a = 10000000000; //编译出错: The literal 10000000000 of type int is out of range
long b = 10000000000L; //编译正确
int c = 1000;
long d = c;
float e = 1.5F;
double f = e;
}
}
a错的原因是,整型数默认为int型,而这个数字大小已经超过了int的范围,又没有在后面加L表示为long所以就错了。b就是很好的修正例子。
例题引出问题2:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
byte p = 3; // 编译正确:int到byte编译过程中发生隐式类型转换
int a = 3;
byte b = a; // 编译出错:cannot convert from int to byte
byte c = (byte) a; // 编译正确
float d = (float) 4.0;
}
}
p正确的原因是首先3是一个int型的数值,并且没有超过int的范围,其次再看这个p的类型为byte,在进行隐式转换没有溢出,包含在byte的范围中。所以正确。
b错误的原因是a是int型的3,虽然这个大小也在byte的范围中。但是在编译过程中,b被赋值的是变量a,事先不知道是否a的大小能在byte范围中。保险起见编译出错。
c正确的原因是加了强制转换
d也是,默认4.0为double型,然后强制转换当然就正确了。可是为什么不像p一样,做隐式转换呢(求大神详解)。好像是浮点存在精度问题,而整型没有。
例题引出问题3:
package com.corn.testcast;
public class TestCast {
public static void main(String[] args) {
int a = 233;
byte b = (byte) a;
System.out.println("b:" + b); // 输出:-23
}
}
看到这里的b输出是一个负数,那么这里的原因是因为,看到int的a=233这个是超过了byte的范围了。然后a强制转换成b,我们先把a换成二进制24位0 + 11101001(int为4个字节 32位) 只取最低的8位,一共截取8位(byte所占用的空间大小)。然后因为最高位为1代表负数 所以b为-23
问题来了,我们看11101001这个二进制表示的不是-23呀,这是怎么得来的-23呢?
原因是计算机中的数据运算都是通过补码来运行的。两个数通过各自补码进行加减运算,得出的补码结果再转成原码就是正确的计算结果。我们看到11101001是溢出的,其实是补码。转成原码后就是-23了。第一位符号位不变,然后取反加1.、
-
不能对boolean类型进行类型转换。
-
不能把对象类型转换成不相关类的对象。
long a=123;//long类型 不加L默认是int 当数字范围在int之内 int自动转long不报错
long b=11111111111;//报错 因为超过了int的范围又不加L
相关考题解析
1.short s1 = 1; s1 = s1 + 1;对还是错 为什么? short s1 = 1; s1 +=1;对还是错 为什么?
2.int 和 Integer 有什么区别?
3.我们能将 int 强制转换为 byte 类型的变量吗?如果该值大于 byte 类型的范围,将会出现什么现象?
4.a = a + b 与 a += b 的区别
-
存在使i + 1 < i的数吗()
答案:存在
解析:如果i为int型,那么当i为int能表示的最大整数时,i+1就溢出变成负数了,此时不就<i了吗。
扩展:存在使i > j || i <= j不成立的数吗()
答案:存在
解析:比如Double.NaN或Float.NaN -
0.6332的数据类型是()
A float B double C Float D Double
答案:B
解析:默认为double型,如果为float型需要加上f显示说明,即0.6332f
网友评论