天天看点

牛客刷题-Java专项练习(2022-3-27)

📢 本文章按照牛客网每日一练上的10道题目上做错的习题来记录错题,并分享解析。

👤 公众号:恩故事还在继续

打卡时间 📅 2022-3-27

题目数量:10    答对题目数:6   准确率:60%

1️⃣ 导出类调用基类的构造器必须用到的关键字: ( C )

A. this
B. final
C. super
D. static      

✏️ 解析

这是一道非常基础的题目,主要的考察点是基类和导出类的概念。
导出类:导出类就是子类,也叫派生类
基类:基类就是父类,也叫超类
题目翻译过来就是:子类调用父类构造器的关键字是什么?
所以可得:子类调用父类构造方法用super()关键字,且放在子类构造函数的第一行。      

2️⃣ 下面代码段输出的结果是什么(D)

class Foo {
    final int i;
    int j;
    public void doSomething() {
        System.out.println(++j + i);
    }
}      
A. 0
B. 1
C. 2      

✏️ 解析

这道题目其实考察的是final关键字,在解题之前我们需要明白它的作用。
1.final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。
2.final变量一旦被初始化后不能再次赋值。
3.final方法不能被重写, final类不能被继承
知道final的作用之后,再去都题目我们便可以很快发现i虽然被定义了但是没有复赋值,所以最后结果就会编译错误。      

📝 补充知识

数据类型 初始值
byte
short
int
long 0L
char ‘u0000’
float 0.0f
double 0.0d
boolean false
所有引用类型 null

3️⃣ 以下语句返回true的是(AB)

Integer a1 = 17, a2 = 17;
Integer b1 = 2017, b2 = 2017;
Integer c1 = new Integer(17);
Integer c2 = new Integer(17);
Integer d1 = new Integer(2017);
int d2 = 2017;      
A. a1==a2
B. d1==d2
C. b1==b2
D. c1==c2      

✏️ 解析

这道题目考察的是基本类型装箱/拆箱对象引用(内存地址)是否相同。
装箱:将基本类型转为引用类型 
拆箱:将引用类型转为基本类型
这里再次说明下:基本类型存在于栈里,引用类型存在堆里
举例说明:
Integer a = new Integer(1); // jdk1.5之前的装箱操作
Integer a1 = Integer.valueOf(1);
Integer a = 1; // jdk1.5 之后的自动装箱
int b = a.intValue(); // 拆箱
int b = a; // 自动拆箱
对于A选项,a1 和 a2 都指向Integr类型,属于自动装箱,所以正确。
对于B选项,Integer和int比较会进行自动拆箱,比较的是数值大小,所以d1==d2返回true。
对于D选项,普通new创建对象,两个new创建两个地址不同的对像,所以c1==c2返回false。
这里着重说下C选项,这个选项涉及到自动装箱的范围。
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.***[i + (-IntegerCache.low)];
        return new Integer(i);
} 
大致的意思是:原来Integer把-128到127(可调)的整数都提前实例化了。对于小于等于127的数值会从Integer内置的缓存中获取Integer对象,对于大于127的数值,由于超出自动装箱的范围,不会使用到缓存,return返回的是新建的对象,所以对象内存地址不同,b1==b2返回false。      

🔗 ​​参考链接:拆箱和装箱​​​    ​​Integer 中的缓存类IntegerCache​​

4️⃣ 有如下四条语句,输出结果为false的是(C)

Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);      
A. System.out.println(i01==i02);
B. System.out.println(i01==i03);
C. System.out.println(i03==i04);
D. System.out.println(i02==i04);      

✏️ 解析

把道题目放在这里的原因主要是可以和第三题作比较,然后还可以补充一点关于这种题型的相关知识点。
值类型(基本类型) “==” 比较的是具体的值,引用类型 “==” 比较的是地址。
1.int与Integer在进行比较的时候,Integer会自动进行拆箱,转换为int与int进行比较,比较的是具体的值。
2.Integer与Integer比较的时候,由于直接赋值的时候会进行自动装箱( Integer a = 1 或 Integer a = Integer.valueOf(1) ),这里需要注意两个问题:
1)当整数范围在-128到127之间时,不需要创建新的Integer对象,而是从缓存(IntegerCache)中获取已经创建好的Integer对象。
2)当大于或小于这个范围的时候,就会直接调用new Integer来创建Integer对象。
所以Integer a = 128 与 Integer b = Integer.valueOf(128) 都创建了新的Integer对象,用“==”比较会返回false
3.Integer a = new Integer(1)和Integer b = 1不同是因为前者会创建对象,存储在堆中,而后者因为在-128到127的范围内,不会创建新的对象,而是从IntegerCache中获取。两者地址不同,用“==”比较自然会返false。
所以对于C选项,因为都是Integer创建的对象所以比较的是地址,两个对象的地址不一致故返回false。