来玩10个易错面试题,总分100,回复您的总分,谢谢!

1.

public class NULL {

     public static void haha(){

        System.out.println("haha");

    }

public static void main(String[] args) {

        ((NULL)null).haha();

    }

}

解析:能正常运行,如去掉static会报空指针。null是任何引用类型的初始值,自然能向下转型为NULL类型,虽然不会报错,但编译会建议直接使用类名调用静态成员,编译过后的class就是直接调用。

2.

class HelloA {
    public HelloA() {
        System.out.println("HelloA");
    }
    { System.out.println("I'm A class"); }
    static { System.out.println("static A"); }
}

public class HelloB extends HelloA {
    public HelloB() {
        System.out.println("HelloB");
    }
    { System.out.println("I'm B class"); }
    static { System.out.println("static B"); }
    
    public static void main(String[] args) {
 new HelloB();
 }
}

解析:new HelloB()会加载HelloB类,即会加载其静态代码块,静态成员,而HelloB为HelloA的子类,即HelloB可能会用到HelloA的类信息,即HelloA应优先于HelloB的任何操作,包括静态代码块,静态成员,构造代码块优先于构造方法。编译后的class文件会优化为如下这样!new HelloB()调用HelloB构造方法,会先隐式调用父类无参构造:super()。除非HelloB的构造方法有显示调用HelloA的有参,这样就不会再掉HelloA的无参;若HelloB有有参构造,而父类无无参构造会编译报错,可以给父类加无参构造,也可以子类的有参构造第一行显示调用父类的有参构造。

故最终结果应该是这样滴。

static A
static B
I'm A class
HelloA
I'm B class
HelloB

3.

public class Dervied extends Base {
    private String name = "dervied";
    public Dervied() {
        tellName();
    }
    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }

    public static void main(String[] args){
        new Dervied();

    }
}
class Base {
    private String name = "base";
    public Base() {

        tellName();
    }

    public void tellName() {
        System.out.println("Base tell name: " + name);
    }
}

解析:子类实例化只是调用父类无参构造, 父类调用的tellName()方法断点会走到子类的tellName()方法,但这时子类并没开始实例化故打印出Dervied tell name: null,调用玩父类无参构造后开始实例化子类,这时name已赋值,再次调用tellName()打印出
Dervied tell name: dervied。但是为什么父类构造的tellName()会调到子类的tellName()?????

4.

 

public class TestDemo {
    private int x = 2;
    static int y = 3;

    public void method() {
        final int i = 100;
        int j = 10;
        class Cinner {
            public void mymethod() {
            这里可以访问x y i j哪几个变量
            }
        }
    }
}

解析:x y i,因为外部类的method()方法可能会先结束出栈,内部类需要copy一份存到自己内部

5.

class TestA  {

    public void start()  {  System.out.println("TestA");  }

    }

    public class TestB extends TestA  {

    public void start()  {  System.out.println("TestB");  }

    public static v.id main(string[]  args)  (

    ((TestA)new TestB()).start();

    }    }

解析:TestB, TestB本来就是TestA类型,编译器会去掉TestB覆盖的start()

6.

解析:a 方法可以覆盖,成员变量不能覆盖,只有向下转型为子类才能输出b

7.

class Base {
   public void method(){
      System.out.print ("Base method");
   }
}
class Child extends Base{  
   public void methodB(){
      System.out.print ("Child methodB");
   }
}
class Sample {
   public static void main(String[] args) {
        Base base= new Child();
      base.methodB();
   }
}

解析:编译失败,base并没有methodB()

8.

class Parent{ 
protected void eat(){
}  
} 
class Child extends Parent { 
   _____  void eat(){
}  
}

解析:public 或 proteced 考查子类要有更高的权限,无修饰符表示的是本包及其在其它包的子类;

9.

class X {
   Y b = new Y();
   X() {
      System.out.print("X");
   }
}

class Y {
   Y() {
      System.out.print("Y");
   }
}

public class Z extends X {
   Y y = new Y();
   Z() {
      System.out.print("Z");
   }
   public static void main(String[] args) {
      new Z();
   }
}

解析:YXYZ,理解了前面这个就没问题了

10.

class Penguin {

private String name=null; // 名字

private int health=0; // 健康值

private String sex=null; // 性别

public void Penguin() {

health = 10;

sex = "雄";

System.out.println("执行构造方法。");

}

public void print() {

System.out.println("企鹅的名字是" + name +

",健康值是" + health + ",性别是" + sex+ "。");

}

public static void main(String[] args) {

Penguin pgn = new Penguin();

pgn.print();

}

}

解析:正解是企鹅的名字是null,健康值是0,性别是null。弄一个长得像构造方法的普通方法来“骗人”,还是挺容易上当;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值