1 对于基本类型void以及它的包装类java.lang.Void,我们都无法直接进行操作。
2 JAVA中的数值类型不存在无符号的,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变。对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。如若想查看byte类型的二进制位数,则
System.out.println(Byte.SIZE);
,若想查看byte类型的最大值和最小值,则
System.out.println(Byte.MIN_VALUE);
System.out.println(Byte.MAX_VALUE);
3 实际上Float.MIN_VALUE和Double.MIN_VALUE分别指的是float和double类型所能表示的最小正数。也就是说存在这样一种情况,0到±Float.MIN_VALUE之间的值float类型无法表示,0到±Double.MIN_VALUE之间的值double类型无法表示。这并没有什么好奇怪的,因为这些范围内的数值超出了它们的精度范围。
4 基本类型存储在栈中,因此它们的存取速度要快于存储在堆中的对应包装类的实例对象。从Java5.0(1.5)开始,JAVA虚拟机(Java Virtual Machine)可以完成基本类型和它们对应包装类之间的自动转换。因此我们在赋值、参数传递以及数学运算的时候像使用基本类型一样使用它们的包装类,但这并不意味着你可以通过基本类型调用它们的包装类才具有的方法。另外,所有基本类型(包括void)的包装类都使用了final修饰,因此我们无法继承它们扩展新的类,也无法重写它们的任何方法。
5 关于各种数据类型之间的赋值
(1) . 未带有字符后缀标识的整数默认为int类型;未带有字符后缀标识的浮点数默认为double类型。
(2). byte、short、char等类型变量只可以由int常量直接赋值而不需要进行强制类型转换,只要不超出其表数范围,不可以由long、float、double直接赋值。但要注意这里是由int常量直接赋值,若是由值为int的表达式赋值则不可,如:
short s = 0;
s = s + 1;
(3).int型值可以赋给所有数值类型的变量,但如果一个整数的值超出了int类型能够表示的范围,则必须增加后缀“L”(不区分大小写,建议用大写,因为小写的L与阿拉伯数字1很容易混淆),表示为long型。long型值可以赋给long、float、double类型的变量;float型值可以赋给float、double类型的变量;double型值只能赋给double类型变量,即long、float、double只能向上赋值。
(4). 编译器会在编译期对byte、short、int、long、float、double、char型变量的值进行检查,如果超出了它们的取值范围就会报错。
6 关于各种数据类型之间的转换
(1)容量小的数据类型自动转换为容量大的数据类型,这里容量是指表示的数的范围,float虽然只有四个字节,但是表示数的范围比八个字节的long要大,故long类型自动转换为float类型
(2)对于“ = ”来说,多种数据类型混合运算时,系统自动将所有数据转换为容量最大的数据类型,再进行运算;当使用+=、-=、*=、/=、%=、运算符对基本类型进行运算时,遵循如下规则: 运算符右边的数值将首先被强制转换成与运算符左边数值相同的类型,然后再执行运算,且运算结果与运算符左边数值类型相同。例如:
public class PrimitiveTypeTest {
public static void main(String[] args) {
short s1 = 1;
// 这一行代码会报编译错误
// s1 = s1 + 1;
// 这一行代码没有报错
s1 = 1 + 1;
// 这一行代码也没有报错
s1 += 1;
}
}
在s1=s1+1;中,s1+1运算的结果是int型,把它赋值给一个short型变量s1,所以会报错;
而在s1+=1;中,由于是s1是short类型的,所以1首先被强制转换为short型,然后再参与运算,并且结果也是short类型的,因此不会报错。
那么,s1=1+1;为什么不报错呢?这是因为1+1是个编译时可以确定的常量,“+”运算在编译时就被执行了,而不是在程序执行的时候,这个语句的效果等同于s1=2,所以不会报错。
7 当使用“==”运算符在基本类型和其包装类对象之间比较时,遵循如下规则:
(1). 只要两个操作数中有一个是基本类型,就是比较它们的数值是否相等。
(2). 否则,就是判断这两个对象的内存地址是否相等,即是否是同一个对象。
// int类型用int类型初始化
int int_int = 0;
// int类型用Integer类型初始化
int int_Integer = new Integer(0);
// Integer类型用Integer类型初始化
Integer Integer_Integer = new Integer(0);
// Integer类型用int类型初始化
Integer Integer_int = 0;
System.out.println("int_int == int_Integer结果是:"
+ (int_int == int_Integer));
System.out.println("Integer_Integer == Integer_int结果是:"
+ (Integer_Integer == Integer_int));
System.out.println();
System.out.println("int_int == Integer_Integer结果是:"
+ (int_int == Integer_Integer));
System.out.println("Integer_Integer == int_int结果是:"
+ (Integer_Integer == int_int));
System.out.println();
运行结果:
1. int_int == int_Integer结果是:true
2. Integer_Integer == Integer_int结果是:false
3. int_int == Integer_Integer结果是:true
4. Integer_Integer == int_int结果是:true
8 Math.round()方法
java.lang.Math类里有两个round()方法,它们的定义如下:
public static int round(float a) {
return (int)floor(a + 0.5f);
}
public static long round(double a) {
return (long)floor(a + 0.5d);
}
看来它们都是将参数值+0.5后交与floor()进行运算,然后取返回值。那么floor()方法的作用又是什么呢?它是取一个小于等于参数值的最大整数。比如经过floor()方法运算后,如果参数是10.2则返回10,13返回13,-20.82返回-21,-16返回-16等等。既然是这样,我们就可以用一句话来概括round()方法的运算效果了:
• Math类的round()方法的运算结果是一个<=(参数值+0.5)的最大整数。
9 switch语句
(1). byte、char、short、int四种基本类型以及它们的包装类(需要Java5.0/1.5以上版本支持)都可以用于
switch语句。
(2). long、float、double、boolean四种基本类型以及它们的包装类(在Java所有版本中)都不能用于
switch语句。
(3). enum类型,即枚举类型可以用于switch语句,但是要在Java5.0(1.5)版本以上才支持。
(4). 所有类型的对象(包括String类,但在Java5.0/1.5以上版本中,该项要排除byte、char、short、int四
种基本类型对应的包装类)都不能用于switch语句。
转自藏圩人--java面试解惑系列,稍作修改