A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 史卫平 黑马帝   /  2011-9-3 00:11  /  1829 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

程序的流程问题,以前还真不是很清楚,看了这题好多了

请列出objBtn_actionPerformed执行时的各语句执行顺序
void objBtn_actionPerformed(ActionEvent e)
{
Child child=new Child();
}
class Base
{
1        int i=0;
2        Other baseOther=new Other(“init Base Other”);
3        private static int x=1;
public Base()
{
4        System.out.println(“Init Base”);
}
}
class Child extends Base
{
5        int a=0;
6        Other childOther=new Other(“init Child Other”);
7        private static int y=2;

public Child()
{
8        System.out.println(“init Child”);
}
}
先不要看答案,看看大家是不是一次性做对


















答案:×3×7×1×2×4×5×6×8×

3 个回复

倒序浏览
黑马网友  发表于 2011-9-3 08:19:09
沙发
从网上找的一段话:
JAVA类首次装入时,会对静态成员变量或方法进行一次初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块级别相同,非静态成员变量和非静态初始化块级别相同。
先初始化父类的静态代码--->初始化子类的静态代码-->
初始化父类的非静态代码--->初始化父类构造函数--->
初始化子类非静态代码--->初始化子类构造函数
回复 使用道具 举报
这个题目我来分析一下:
注意两条原则:初始化一个类必先初始化它的父类,初始化一个类必先初始化它的属性。
首先new一个child的时候,jvm需要加载类child,此时注意到它有一个父类,所以先去加载父类,由于静态域是再类加载的时候初始化,所以首先初始化了3,之后加载child初始7, 这时由于是用new创建的子类对象child所以,必先初始化它的父类Base,然后就是初始父类的属性,所以就是1→2,这样父类就先创建对象4,最后就是子类的初始化类似的5→6→8

评分

参与人数 1技术分 +2 收起 理由
wangfayin + 2 不错啊!

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-9-3 17:18:40
板凳
这个我看视频的时候也是模棱两可,现在总结一下,和大家分享;
这个应该主要是子类对象的实例化过程,我想只要这个过程清晰了,其它的过程,就了解了。
下面以小程序的方式说明:[code=java]class ;P erson  
{  
    public String name = "unkonwn";  
    public int age = -1;  
      
    public ;P erson()  
    {  
    }  
    public ;P erson(String name,int age)  
    {  
        this.name = name;  
        this.age = age;  
    }  
  
  
    public void getInfo()  
    {  
        System.out.println("name= " + name +"\n" + "age = " + age);  
    }  
}  
  
  
class Student extends ;P erson  
{  
    public String school = "unkonwn";  
    public Student()  
    {  
        super();  
    }  
    public Student(String name, int age)  
    {  
        super(name,age);  
    }  
    public Student(String name,int age ,String school)  
    {  
        this(name,age);  
        this.school = school;  
    }  
    public void study()  
    {  
    }  
}  
  
  
class TestStudent  
{  
    public static void main(String [] args)  
    {  
        Student st = new Student("xiaobai",20,"Ncist");  
        st.getInfo();  
    }  
}  [/code]

分析:
      1)当new Student 对象时,会在内存中产生一个Student 对象,产生该对象以后,为该对象分配存储空间,并进行默认的初始化,即name,age,school分别设置为 Null,0,Null;
      2)绑定构造方法的参数,"xiaobai",20,"Ncist" 是传递的实际参数,编译器会将这些实际参数传递给构造方法Student(String name,int age ,String school)的形式参数,即形式参数即name,age,school分别设置为 xiaobai,20,Ncist;
      3)编译器不会直接执行构造方法,在执行构造方法之前,编译器首先检查是否存在 this 调用,即是否调用其它的构造函数,若存在,程序便去执行this调用的其它构造函数,执行的过程也是同样的过程。例如:Student 类在执行 Student(String name,int age ,String school) 构造方法时,方法中存在 this(name,age)调用,继而程序执行 Student(String name, int age) 构造方法,执行结束后,继续执行Student(String name,int age ,String school) 构造方法中的其它程序代码;
     4)如果构造方法中不存在 this 调用,便去调用父类的构造方法,调用父类的构造方法分为隐式调用和显示调用两种,如果构造方法中没有 super (),系统会默认为该构造方法加上 super(),此种调用称为隐式调用。如:构造方法 Student(String name, int age) 中没有 super(name,age) ,系统会默认的加上 super()。构造方法中明确写出了super()这种调用称为显示调用。父类的构造方法又按照以上流程执行。显示或隐式调用父类的构造方法一直追溯到Object 类为止。
     5)当父类的构造方法执行完成以后,又回到子类的构造方法上来。子类的构造方法继续往下执行。

         子类构造方法的执行过程:
         对实例变量进行显示的初始化;如:Student(String name,int age ,String school)构造方法,在执行完 super() 构造方法后,程序会执行 public String school = "unkonwn"; 对school 进行显示的初始化;
         执行完显示初始化的语句后,才真正开始执行构造方法体中自己的代码,即 this.school = school 至此,子类对象的实例化过程完成。

评分

参与人数 1技术分 +2 收起 理由
wangfayin + 2 回答的很好!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马