zoukankan      html  css  js  c++  java
  • java-this和super

     1 public class Parent {
     2   protected String name = "parent";
     3   public Parent() {
     4     System.out.println(this.name);//parent
     5     fun();//son name: son
     6   }
     7 
     8   protected void fun() {
     9     System.out.println("parent name: " + name);
    10   }
    11 }
    12 
    13 public class Son extends Parent{
    14   protected String name = "son";
    15   public Son() {
    16   }
    17   
    18   protected void fun() {
    19     System.out.println("son name: " + name);
    20   }
    21 }

    实例化一个Son对象,会发现输出

    parent
    son name: son

    也就是说Parent的构造函数中,this.name的this为Parent,this.fun()的this为Son,这是为什么呢?其实Parent中的this始终都是Son,但由于字段的取值取决于实例的静态类型,而不是向invokevirtual那样取决于实际类型,我们都知道java方法的第一个参数永远是this(除了静态方法,this的作用就是连接实例对象,从而操作实例字段、实例方法,而静态方法并不会与某个实例关联,故静态方法不会传入this,也就不能操作实例字段、实例方法了),当Son构造器调用Parent构造器时传入的this,一定经过了类似向上转型的过程(猜测是这样),从而this的静态类型在Parent看来是Parent类型的。

    这就解释了为什么在Parent中的this.name是Parent的字段,那么this.fun()是Son的怎么解释呢?这就是invokevirtual的威力了,invokevirtual会在运行时动态判断调用者的实际类型,从而决定调用方法的版本。

     1 public class Parent {
     2   protected String name = "parent";
     3 
     4   protected void fun() {
     5     System.out.println("parent name: " + name);
     6     fun();
     7   }
     8 }
     9 
    10 public class Son extends Parent{
    11   protected String name = "son";
    12   private boolean flag = false;
    13   
    14   protected void fun() {
    15       if(!flag) {
    16           flag = true;
    17           super.fun();
    18       }else{
    19           System.out.println("son name: " + name);
    20       }
    21   }
    22 }

    再来看上面这个例子,new Son().fun()一定是输出

    parent name: parent
    son name: son

    因为super.fun()会传入向上转型的this,从而在进行字段输出时输出parent,调用方法fun()时又会使用invokevirtual指令寻找实际类型,所以会调用Son的fun()方法,而此时传入的this又会向下转型为Son,故输出字段为son。

  • 相关阅读:
    华为 VRP系统管理
    清除远程桌面登陆记录
    windows多用户登陆
    破解win7系统密码
    ms10-061漏洞复现
    通达OA任意用户登录漏洞复现(POC+手工方式实现)
    Windows五次Shift漏洞
    CODESYS V3远程堆溢出漏洞复现(环境配置+复现过程)
    工控软件DLL劫持漏洞复现
    Redis远程命令执行漏洞复现
  • 原文地址:https://www.cnblogs.com/holoyong/p/7510398.html
Copyright © 2011-2022 走看看