当前位置 博文首页 > 果咩:震惊!这么简单的java基础题竟然都做错了!!
《Java面试十八式》------第三式【水晶之恋】
水晶之恋:java虐我千百遍,我待java为初恋,找回你被java初虐的感觉
害,一不小心用了震惊体,主要是前几篇文章观看者寥寥无几,连个提意见的都没有,看来是缺少干货,这篇文章,主要来测验下你是否肾虚,不对,测验你的java的基础是否牢靠。
在没有疫情之前,我们去面试肯定少不了笔试这一轮,现在虽然电话面试居多,但是基础可不能少
以下习题来自牛客网,首先声明我不是打广告,我是真的在牛客网刷题的,发现自己的底子确实很差
我这里为大家总结几种题型,其中包括 String,类型转换,类的初始化,多态,数组,i++,标识符 等问题
大家肯定在想,这种题型你也考我,太简单了吧!
莫慌,各位看官继续往下看。
一、String s = new String(“xyz”);创建了几个StringObject?
A. 两个或一个都有可能
B. 两个
C. 一个
D. 三个
A. (a+b).equals( c )
B. a+b == c
C. c == d
D. c.equals(d)
第一题:选A
解析:因为new字符串对象的时候,肯定会在堆中创建一个新的对象,然后他还会去看常量池是否有这个字符串,没有则创建,有就不创建,所以有可能是两个或者一个。
第二题:选A D
解析:
A选项:因为使用equals比较的是值是否相等,所以A正确
B选项:这里a和b使用的是变量,所以肯定是一个新的对象,所以和c的地址不相等
C选项:c和d都创建了新的对象 ,不相等
D选项,比较值,所以相等
==和equals的区别
==:既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
equals: 他是java.lang.Object里的方法 如果没有被重写默认和==是一样的,如果复写过看具体复写的方法,但是String中的equals方法重写后比较的值是否相等
String对象的创建和比较
//①常量之间的比较
String a = "a";
String aa = "a";
System.out.println(aa == a ); //true
System.out.println(aa.equals(a) ); //true
//②常量相加
String a = "a";
String b = "b";
String c = "a" + "b";
System.out.println("a"+"b" == c ); //true
System.out.println(a+b == c ); //false
常量对象相加(“a”+“b”):会把"a" + “b” 优化成 “ab”
变量对象相加(a+b):只会在堆中产生新的对象
//③变量之间比较
String a = new String("a");
String aa = new String("a");
System.out.println(aa == a ); //false
System.out.println(aa.equals(a)); //true
对象创建:
在创建对象时因为使用了new关键字,所以肯定会在堆中创建一个对象。然后会在常量池中看有没有要创建的字符串;如果没有 此时还会在常量池中创建一个;如果有 则不创建。所以一共会产生两个对象,每次创建新对象的地址都是不同的
//④变量+常量之间的比较
String a = "a";
String b = new String("b");
String c = a + "b";
System.out.println(a + b == c );//false
关于a + "b"的执行过程:
底层会生成一个StringBuilder对象,随后调用SringBuilder中的append方法进行拼接,最后利用 StringBuilder.toString()的方法返回一个新的String对象,所以只要和变量相加就会产生新的对象
例:
new StringBuilder.append(a).append(“b”).toString();
一、下面赋值语句中正确的是(多选)()
A. double d = 5.3e12;
B. float f = 11.1;
C. int i = 0.0;
D. Double oD = 3;
E. short s = 1; s = s + 1;
F. short s = 1; s += 1;
二、下面输出正确的是()
public class Test2
{
public void add(Byte b)
{
b = b++;
}
public void test()
{
Byte a = 127;
Byte b = 127;
add(++a);
System.out.print(a + " ");
add(b);
System.out.print(b + "");
}
}
A. 127 127
B. 128 127
C. 129 128
D. 以上都不对
三、关于下面代码片段叙述正确的是()
byte b1=1, b2=2, b3, b6;
final byte b4=4,b5=6;
b6=b4+b5;
b3=(b1+b2);
System.out.println(b3+b6);
A. 输出结果:13
B. 语句:b6=b4+b5编译出错
C. 语句:b3=b1+b2编译出错
D. 运行期抛出异常
第一题:选A F
解析:
A. 正确
B. 错误,11.1默认是double类型,double转型float需要强转,可用(float)11.1或11.1f
C. 错误,需要强转
D. 错误,Double是包装类,(自动装箱的目标必须严格对应它拆箱后的类型)
E. 错误,s + 1 最后的类型为int,转化成short需要强转
F. 正确,+= 会自动类型转换为前面的变量类型
第二题:选D
解析: public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包(AutoBoxing/UnBoxing) Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。 add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127
第三题:选C
解析:被final修饰的变量是常量,这里的b6=b4+b5可以看成是b6=10;在编译时就已经变为b6=10了
而b1和b2是byte类型,java中进行计算时候将他们提升为int类型,再进行计算,b1+b2计算后已经是int类型,赋值给b3,b3是byte类型,类型不匹配,编译不会通过,需要进行强制转换。
1.类型自动转换:低类型可以直接转换成高类型,Java中的byte,short,char进行计算时都会提升为int类型,注意计算结果为int类型,
2.强制类型转换:高类型若转为低类型,必须进行强制类型转换
3.强转发生的溢出或精度的下降:Byte类型值大小为-128~127之间,发生越界会从-128重新计算
4.final修饰的如何强转(常量):常量相加,加完之后看是否在数据类型范围内,如果不在则报错
5.包装类如何转化:包装类赋值的时候,严格对应精度,不会发生自动转换
6.+=的类型转换问题:+ 不会自动类型转换;+= 会自动类型转换为前面的变量类型
一.下面代码的输出是什么?
public class Base{
private String baseName = "base";
public Base(){
callName();
}
public void callName(){
System. out. println(baseName);
}
static class Sub extends Base{
private String baseName = "sub";
public void callName(){
System. out. println (baseName) ;
}
}
public static void main(String[] args){
Base b = new Sub();
}
}
A. null
B. sub
C. base
二.下面代码的输出是什么?
public class P {
public static int abc = 123;
static{
System.out.println("P is init");
}
}
public class S extends P {
static{
System.out.println("S is init");
}
}
public class Test {
public static void main(String[] args) {
System.out.println(S.abc);
}
}
A. P is init,123
B. S is init,P is init,123
C. P is init,S is init,123
D. S is init,123
三.下面代码的输出是什么?
class Test {
public static void main(String[] args) {
System.out.println(new B().getValue());
}
static class A {
protected int value;
public A (int v) {
setValue(v);
}
public void setValue(int value) {
this.value= value;
}
public int getValue() {
try {
value ++;
return value;
} finally {
this.setValue(value);
System.out.println(value);
}
}
}
static class B extends A {
public B () {
super(5);
setValue(getValue()- 3);
}
public void setValue(int value) {
super.setValue(2 * value);
}
}
}
A. 6 7 7
B. 22 34 17
C. 22 74 74
D. 11 17 34
第一题:选 A
解析:首先创建子类对象,要先进行父类初始化,在父类初始化构造器的时候 调用的className()方法,因为我们创建的是子类实例,所以调用的是子类的className()方法,子类方法的baseName使用的是子类的属性,但是子类还未进行初始化,所以子类当前的baseName为null
第二题:选 A
解析:子类引用父类的静态字段,只会触发子类的加载、父类的初始化,不会导致子类初始化 而静态代码块在类初始化的时候执行,所以子类的静态代码块不会执行
第三题:选 B
解析:new B()创建子类实例,调用父类有参构造区super(5); 因为创建的是子类实例,所以这里的setValue(5)调用的是子类的,然后是super.setValue(2 * 5);到此value的值 = 10;