一道java面试题,对结果很不理解,求详解

tfx9191 2016-07-27 04:42:50
class A{
int a = 3;
public A(){
printA();
}
public void printA(){
System.out.println(a);
}
}
class B extends A{
int a = 6;
public B(){
printA();
}
}
public static void main(String[] args)
{
A a = new B();
}
...全文
1104 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinjiawudi 2016-08-02
  • 打赏
  • 举报
回复
besty_wang 2016-08-02
  • 打赏
  • 举报
回复
我不知道为什么在我这儿编译不过 A a = new B(); // Multiple markers at this line - The value of the local variable a is not used - No enclosing instance of type Task1 is accessible. Must qualify the allocation with an enclosing instance of type Task1 (e.g. x.new A() where x is an instance of Task1).
NewMoons 2016-07-31
  • 打赏
  • 举报
回复
楼主是来逗比的么? 结果明明是3,3。这样浪费别人时间很不好,csdn很生气,后果很严重。
ok406lhq 2016-07-31
  • 打赏
  • 举报
回复
你题目忘了B类重写A类的方法吧,弟弟
iamihanfei 2016-07-31
  • 打赏
  • 举报
回复
我运行结果明明是3,3,楼主是不是哪里写错了
泰 戈 尔 2016-07-31
  • 打赏
  • 举报
回复
0,6的原因是:

子类没有override父类的printA方法,在new 一个B类的时候,并没有newA类,然而却在B类中调用了printA方法,所以会默认先输出0
ljheee 2016-07-29
  • 打赏
  • 举报
回复
结果 运行出来是0 ,6 吗?
K_Candid 2016-07-28
  • 打赏
  • 举报
回复
是这样的,其实对象类型可以分为编译型类型和运行时类型, 这里的A a=new B()其实根据引用变量可以判断编译时类型为 A类,根据new B()可以知道运行时类型为B类,实例化B的时候, 调用A的构造函数,构造器中掉用的方法其实是运行时类型的方法,也就是 B类的printa()方法,然而B中的属性a此时还没有初始化,就是你第一个打印结果0. 然后调用B的构造函数,这个时候,a已经初始化,所以打印结果就是6了;
tfx9191 2016-07-28
  • 打赏
  • 举报
回复
引用 11 楼 Molly_1994的回复:
[quote=引用 10 楼 qq_29890513 的回复:] [quote=引用 9 楼 qq_29890513的回复:][quote=引用 8 楼 soton_dolphin的回复:][quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧[/quote] 调用父类构造器时 调用的是重写的方法 是不是可以理解为就近调用呢 我还以为调用父类构造器时会初始化父类的属性[/quote] 调用父类构造器时确实会初始化父类的属性,只是这里调用的不是父类方法[/quote] 懂了 谢谢 我代码少写了你也看出来了
sky_08_06_02 2016-07-28
  • 打赏
  • 举报
回复
垒这么高
crusher395 2016-07-28
  • 打赏
  • 举报
回复
完整的初始化顺序是: 父类静态变量 父类静态块 子类静态变量 子类静态块 父类非静态变量 父类非静态块 父类构造函数 第一次 子类非静态变量 子类非静态块 子类构造函数 第二次 第一次是执行父类构造函数时带到了子类重写的printA(),此时子类的a没有初始化默认为0,所以第一行b:0 第二次是执行子类构造函数,此时已经经过子类非静态变量,所以第二行是b:6
Java-我去 2016-07-28
  • 打赏
  • 举报
回复
引用 13 楼 qq_29890513 的回复:
[quote=引用 11 楼 Molly_1994的回复:][quote=引用 10 楼 qq_29890513 的回复:] [quote=引用 9 楼 qq_29890513的回复:][quote=引用 8 楼 soton_dolphin的回复:][quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧[/quote] 调用父类构造器时 调用的是重写的方法 是不是可以理解为就近调用呢 我还以为调用父类构造器时会初始化父类的属性[/quote] 调用父类构造器时确实会初始化父类的属性,只是这里调用的不是父类方法[/quote] 懂了 谢谢 我代码少写了你也看出来了[/quote]
引用 13 楼 qq_29890513 的回复:
[quote=引用 11 楼 Molly_1994的回复:][quote=引用 10 楼 qq_29890513 的回复:] [quote=引用 9 楼 qq_29890513的回复:][quote=引用 8 楼 soton_dolphin的回复:][quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧[/quote] 调用父类构造器时 调用的是重写的方法 是不是可以理解为就近调用呢 我还以为调用父类构造器时会初始化父类的属性[/quote] 调用父类构造器时确实会初始化父类的属性,只是这里调用的不是父类方法[/quote] 懂了 谢谢 我代码少写了你也看出来了[/quote] 对头
GHOST64 2016-07-27
  • 打赏
  • 举报
回复
用eclipse运行楼主的原代码 结果是 3 3
anakin_feng 2016-07-27
  • 打赏
  • 举报
回复
引用 10 楼 qq_29890513 的回复:
[quote=引用 9 楼 qq_29890513的回复:][quote=引用 8 楼 soton_dolphin的回复:][quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧[/quote] 调用父类构造器时 调用的是重写的方法 是不是可以理解为就近调用呢 我还以为调用父类构造器时会初始化父类的属性[/quote] 调用父类构造器时确实会初始化父类的属性,只是这里调用的不是父类方法
tfx9191 2016-07-27
  • 打赏
  • 举报
回复
引用 9 楼 qq_29890513的回复:
[quote=引用 8 楼 soton_dolphin的回复:][quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧[/quote] 调用父类构造器时 调用的是重写的方法 是不是可以理解为就近调用呢 我还以为调用父类构造器时会初始化父类的属性
tfx9191 2016-07-27
  • 打赏
  • 举报
回复
引用 8 楼 soton_dolphin的回复:
[quote=引用 6 楼 Molly_1994 的回复:] 这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6[/quote] 看懂了点 就是说实例化B的时候 先调用父类构造器 父类构造器调用重写的方法 调用父类构造器时不会初始化已类的属性 只有调用完父类构造器 调用自己的构造器的时候才会初始化属性 对吧
soton_dolphin 2016-07-27
  • 打赏
  • 举报
回复
引用 6 楼 Molly_1994 的回复:
这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
在初始化B()的时候,先调用A的构造器,在因为B重写了printA()方法,所以在A构造器执行的时候调用了B的printA()方法,而此时B还没有被完全初始化,所以B里面a 变量还是0,第一行就打印出0来。当B构造器执行完毕以后,a被赋值6,所以第二行是6
soton_dolphin 2016-07-27
  • 打赏
  • 举报
回复
我只看到 3,3, 没看到0, 6
anakin_feng 2016-07-27
  • 打赏
  • 举报
回复
这样0,6能看明白吗
class A {
    int a = 3;

    public A() {
        printA();
    }

    public void printA() {
        System.out.println("a:"+a);
    }
}

class B extends A {
    int a = 6;

    public B() {
        printA();
    }

    public void printA() {
        System.out.println("b:"+a);
    }

    public static void main(String[] args) {
        A a = new B();
    }
}
anakin_feng 2016-07-27
  • 打赏
  • 举报
回复
引用 4 楼 qq_29890513 的回复:
[quote=引用 2 楼 Molly_1994的回复:]1.父类不能访问子类属性。 2.这里子类没有重写父类printA()方法 所有调用的全是父类的printA()方法
我知道这个 结果是0,6 不理解0怎么来的[/quote] 0,6?那你代码错了吧,我输出了都不是0,6
加载更多回复(4)

62,624

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧