前言:
在学习Java的过程中,基本数据类型是我们一开始就接触到的,很多小伙伴对它是既熟悉又陌生,虽然经常在用,但对其的一些使用细节还是有待提高,因此想要完全掌握它们,还是需要我们平时多留些心思,那么,今天就给大家分享几道有关基本数据类型的面试题目,快来看一看你能答出来几道?
1. String是基本的数据类型吗?
不是
- Java中的基本数据类型只有8个,即:byte (字节型)、short (短整型)、int (整型)、long (长整型)、float (单精度浮点型)、double (双精度浮点型)、char (字符型)、boolean (布尔型)
- 除了基本类型 (primitive type),剩下的都是引用类型 (reference type),Java 5以后引入的枚举类型也是一种比较特殊的引用类型
2. float f = 3.4; 是否正确?
不正确
3.4是双精度数,将双精度浮点型 (double) 赋值给单精度浮点型 (float) 属于下转型 (down-casting,也称为窄化) 会造成精度损失,因此需要强制类型转换float f = (float) 3.4; 或者写成 float f = 3.4F;
3. 以下写法是否有错吗?
short s1 = 1; s1 = s1 + 1;
short s1 = 1; s1 += 1;
对于 short s1 = 1; s1 = s1 + 1;不能正确编译: 由于1是int类型,因此 s1+1 运算结果也是int类型,需要强制转换才能赋值给short类型
对于 short s1 = 1; s1 += 1; 可以正确编译:因为s1 += 1; 相当于 s1 = (short)(s1+1); 其中隐含有强制类型转换
4. int和Integer有什么区别?
Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型
为了能够将这些基本数据类型当做对象操作,Java为每一个基本数据类型都引入了对应的包装 (wrapper class)
int类型对应的包装类就是Integer,从Java 5开始引入自动装箱/拆箱机制,使得二者相互转换
Java为每个原始类型都提供了包装类型:
-
原始类型:boolean,char,byte,int,long,float,double
-
包装类型:Boolean,Character,Byte,Integer,Long,Float,Double
原始类型 包装类型 boolean Boolean char Character byte Byte int Integer long Long float Float double Double
5.自动拆箱和装箱扩展
与自动拆箱和装箱有关的其他面试题:
5-1面试题目一
- 示例代码
public class AutoUnboxingTest {
public static void main(String[] args) {
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
System.out.println(a==b);
System.out.println(a==c);
}
}
请根据以上示例代码,判断出两个输出结果分别为什么?
正确答案:false和true
快看看你答对了吗?如果不对,请查看下面的解析过程
- 代码分析:
public class AutoUnboxingTest {
public static void main(String[] args) {
Integer a = new Integer(3); //a是Integer类的实例化对象,属于引用类型
Integer b = 3; //将3自动装箱成Integer类型
int c = 3; //整型变量c
//a是引用类型,引用的是堆中的内存地址,b是在栈中的变量值
System.out.println(a==b); //值为false,两个引用没有引用同一对象
//c也是在栈中的变量值,a会自动拆箱成int类型再与c比较
System.out.println(a==c); //值为true,都属于基本类型的变量值
}
}
5-2 面试题目二
public class AutoUnboxingTest2 {
public static void main(String[] args) {
//分别定义四个Integer类型的变量,f1和f2值为100,f3和f4值为150
Integer f1 = 100,f2 = 100,f3 = 150, f4 = 150;
//分别比较以上赋值相同值的变量,观察其结果是否相同
System.out.println(f1==f2);
System.out.println(f3==f4);
}
}
面试时我们很容易被这道题所迷惑,可能会得出要么都是false,要么都是true的错误结论
但是我们需要注意,这里的四个变量f1、f2、f3和f4都是Integer对象引用的,所以下面的==比较的不是值而是引用
再回答这道题前,请先思考一个问题:装箱的本质究竟是什么?
当我们给一个Integer对象赋一个int类型的值时,会调用Integer类的静态方法valueOf
- 这里提到了ValueOf方法,很多小伙伴对它还是比较陌生的,让我们来一起查看一下valueOf方法的源码,可能就会得出我们想要的答案:
//返回值为Integer类型的静态方法valueOf,参数为一个整型变量i
public static Integer valueOf(int i) {
//判断i是否在的Integer对象的低位和高位范围内
if (i >= IntegerCache.low && i <= IntegerCache.high)
//如果满足条件,返回一个下标为i和低内存地址值之差的cache数组值
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果超出这个范围,将会重新初始化i变量的值,即new一个新的Integer对象
return new Integer(i);
}
- 在valueOf方法中,我们看到了一个IntegerCache类,那么它到底是什么呢?让我们继续查看该类的源码来一探究竟
public final class Integer extends Number implements Comparable<Integer> {
...
//IntegerCache是Intger类的一个内部类
private static class IntegerCache {
//静态终极的整型变量low(表示低位)初始化值为-128
static final int low = -128;
//整型变量high(高位)未定义初值
static final int high;
//Intger类型的cache数值
static final Integer cache[];
//静态代码块
static {
// 定义局部变量h赋初值为127
int h = 127;
//通过反射获取字符串变量integerCacheHighPropValue的值
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
//如果integerCacheHighPropValue的值不为空
if (integerCacheHighPropValue != null) {
try {
//将字符串变量integerCacheHighPropValue转换为int型并把值赋给i变量
int i = parseInt(integerCacheHighPropValue);
//i变量的取值范围在i到127之间
//max方法:如果左边大于右边值,最大值为左边,否则为右边
i = Math.max(i, 127);
// h变量的取值范围在i和数组最大值(Integer.MAX_VALUE)与低位值(low)之和减1
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
//如果字符串变量integerCacheHighPropValue不能被转换为整型就忽略它
}
}
//integerCacheHighPropValue值为空就把h变量的值赋给high(高位)
high = h;
//通过new一个Intger对象来实例化cache数组,其下标为高低位之差加1
cache = new Integer[(high - low) + 1];
int j = low;// 将低位(low)值赋给j变量
//遍历cache数组
for(int k = 0; k < cache.length; k++)
//将每次低位加1的值存入cache数组中
cache[k] = new Integer(j++);
// int型的值范围必须在[-128, 127]内
//断言IntegerCache对象的high(高位)值是否大于等于127
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
...
}
其实IntegerCache就是Intger对象的一个内部类,其中有一个low变量 (表示低位),其值为-128,而另一个high变量 (高位),其值为127 ,以及一个cache数组用来存放整型变量
//返回值为Integer类型的静态方法valueOf,参数为一个整型变量i
public static Integer valueOf(int i) {
//判断i是否在的Integer对象的低位和高位范围内
if (i >= IntegerCache.low && i <= IntegerCache.high)
//如果满足条件,返回一个下标为i和低内存地址值之差的cache数组值
return IntegerCache.cache[i + (-IntegerCache.low)];
//如果超出这个范围,将会重新初始化i变量的值,即new一个新的Integer对象
return new Integer(i);
}
valueOf方法的作用:判断i变量是否在IntgerCache类的low (低位) 值和high (高位)值范围内,即整型变量i要在-128到127范围内,如果满足条件将会返回常量池中的Intger对象,如果超出这个范围,将会new一个新的Intger对象
public class AutoUnboxingTest2 {
public static void main(String[] args) {
//四个Integer类型的变量,f1和f2值为100,f3和f4值为150
Integer f1 = 100,f2 = 100,f3 = 150, f4 = 150;
//f1和f2的值为100,都在[-128,127]这个条件范围内
System.out.println(f1==f2); //值为true,在堆中引用常量池中的变量值
//而f3和f4的值为150,已经超出[-128,127]这个条件范围了
System.out.println(f3==f4); //值为false,引用的堆中Intger对象的内存地址
}
}
这道题看似简单,但实际上却暗藏玄机,需要面试者具有相当深厚的功力
好了,今天有关基本数据类型的一些常见面试题目的学习,到这里就结束了,欢迎大家学习和讨论!
参考视频链接:
https://www.bilibili.com/video/BV1Eb4y1R7zd (B站UP主程序员Mokey的Java面试100道)
参考博客链接:
https://blog.csdn.net/jackfrued/article/details/44921941 (Java面试题全集(上))