java动态绑定

入博客园第一天,记录个java动态绑定一个小知识,先铺代码
场景1
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        A a = B.class.newInstance();
        Field field = A.class.getDeclaredField("str");
        field.setAccessible(true);
        System.out.println(field.get(a));
    }

    static class A {
        private String str = "AAA";
    }

    static class B extends A {
        private String str = "BBB";
    }

 以学java时候的知识,子类指向父类,想当然的会以为这里的输出是BBB,但是这里的结果并不是。

通过编译器输出的结果为AAA

场景二

代码稍加改造

public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
A a = B.class.newInstance();
Field field = A.class.getDeclaredField("str");
field.setAccessible(true);
System.out.println(a.getStr());
}

static class A {
private String str = "AAA";

public String getStr() {
return this.str;
}
}

static class B extends A {
private String str = "BBB";
}

 这个场景依然输出的是 AAA

打个断点分析分析

 虽然运行的是类B,但B里面没有这个方法,就找父类里面的此方法,this.str 即为 A里面 声明的str,理所当然输出的是 AAA

场景三

public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        A a = B.class.newInstance();
        Field field = A.class.getDeclaredField("str");
        field.setAccessible(true);
        System.out.println(a.getStr());
    }

    static class A {
        private String str = "AAA";

        public String getStr() {
            return this.str;
        }
    }

    static class B extends A {
        private String str = "BBB";
        @Override
        public String getStr() {
            return this.str;
        }
    }

这个就是经典的调用子类指向父类,输出BBB

最后小小总结一波

 

动态绑定原则
  1. 方法看对象的运行类型
  2. 属性看对象的编译类型

 

感觉没说明白

首先说说啥事运行类型,啥是编译类型

A a = new B(); A是编译的类型,B是运行的类型

拿属性看你声明的是啥,拿方法看你具体创建的对象。

posted @ 2022-05-24 22:56  chiangkkk  阅读(27)  评论(0)    收藏  举报