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。弄一个长得像构造方法的普通方法来“骗人”,还是挺容易上当;