多态机制的深入了解以及finally中涉及的小细节1

class Test {
    public static void main(String[] args) {
        System.out.println(new B().getValue());
    }
    static class A {
        protected int value;
        public A (int v) {
            setValue(v);
        }
        public void setValue(int value) {
            this.value= value;
        }
        public int getValue() {
            try {
                value ++;
                return value;
            } finally {
                this.setValue(value);
                System.out.println(value);
            }
        }
    }
    static class B extends A {
        public B () {
            super(5);
            setValue(getValue()- 3);
        }
        public void setValue(int value) {
            super.setValue(2 * value);
        }
    }
}

上述程序的输出是22 34 17,

解析:1程序启动时进入main方法程序入口,创建B类的实例对象然后调用其继承A类的getValue方法,

2调用B类的构造方法时,显示的调用了父类的构造方法,在父类的构造方法中调用了setValue()方法,这时需要注意,

由于子类B重写了父类A的setValue,由于Java实现了动态绑定机制(也就是在运行时根据对象的信息来绑定到底调用哪个类上的方法),这时调用的是B类的setValue方法,此时属性value的值是10

3当经过上面一个步骤后,父类对象已经安全完整的构造好了,接下来子类对象还未完全构造好,此时调用setValue(getValue-3),getValue调用的是A类上的方法(B类继承而来),这里就是接下来的关键所在:首先value此时为10,在try块中实现value++,然后进入finally块中调用setValue方法(这时还是调用的B类中的方法,因为this指代的是B类的对象,在调用getValue方法中编译器会自动传入一个this参数到getValue方法,这个事情是编译器帮我们做好了,我们不能这么做),那么此时value为11,调用setValue后value的值就为22了,所以第一次输出22,但是在try块中return返回的是value++以后的值,也就是11,所以此时B类构造器里调用setValue(11-3)以后,value的值就为16

4经过2,3两个步骤,子父类对象基本构建完毕,此时在main方法中调用新建B类对象的getValue方法,value先自增,return暂存value的值17,随后进入finally,调用setValue(),然后输出value的值为17*2=34,最后返回value的值为17

这个程序很好的讲解了动态绑定机制同时还顺带说了下try-finally的特性

猜你喜欢

转载自blog.csdn.net/m0_38078065/article/details/86750036