class A{
static{
System.out.print("1");
}
public A(){
System.out.print("2");
}
}
class B extends A{
static{
System.out.print("a");
}
public B(){
System.out.print("b");
}
}
public class Hello {
public static void main(String[] args) {
// TODO Auto-generated method stub
A ab = new B();
ab = new B();
}
}
请将输出写出,以及详细分析~
个人理解:只要你用到一个类首先执行Static,所以 A ab这句话等于说在栈内存中分配了一块区域叫ab:xxxx但什么都没有做,关键就在于new B() ,这个时候首先B是从A中继承而来,因此D
到( class B extends A )这里 会先进入A中而这个时候A中的Static语句自动执行于是出现"1",而并没有调用其方法,接着继续执行 B { ...}当然本意想调用构造方法但刚进入 B中Static又抢先执行于是出现 "a",然后继续调用构造方法,java中的规矩调用子类构造方法之前必须先调用相应的父类构造方法,因此执行了父类的构造方法后再执行的 B 中的语句于是出现了2b; 最后那个(ab = new B())相当于在堆内存中又生成一块区域,然后将ab 的引用指向了新的这个区域。可能疑惑就出在这里吧为什么第二次没有回到A中而且第二次没有执行Static 语句;这个我觉得这个是因为在JAVA中为了提高效率第二次new对象时是直接通过 第一次new B();的过程中的构造方法因此不管你以后在哪里new B();都不会在去浏览class A class B 全局了;也就是只在第一次产生对象时候浏览全局以后就可以直接准确的找到你要的方法,你可以这么理解就当做JAVA虚拟机在第一次浏览全局的时候已经帮你整理了所有方法以后可以准确找到而不用重新寻找。你可以做测试验证,当然第一次那句 A ab = new B();中这种模式常用但你如果换成B ab = new B();只要之前没有new 过B运行结果依然会是 1a2b2b.具体官方解释你得参看JAVA的相关帮助文档.
A ab = new B(); 走完这一句会输出 12ab
ab = new B(); 走完这一句会输出 2b
分析:
static(静态代码块、从句)只会在类加载第一次的时候调用
而构造函数在每次构造对象的时候都会调用
如果一个类之间有继承关系的话
那么在构造子类对象的时候会先调用父类的构造函数加载父类的信息
然后调用子类的构造函数 将子类对象初始化完毕
综上,
当执行 A ab = new B();时 调用顺序如下:
A类的从句(A类第一次加载)
A类构造函数
B类的从句(B类第一次加载)
B类构造函数
当执行 ab = new B(); 时 调用顺序如下:
A类构造函数
B类构造函数
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息