看到了這樣一個問題((JAVA)關於this的一個細節問題)

看到了這樣一個問題,http://www.oschina.net/question/555043_242782java

回答一下,寫下來。 this

問題: spa

package t4;
 
    class Father{       
        private void print()
        {   
            System.out.println("Father") ;
        }
        public void fun()
        {   
            System.out.println(this);
            this.print() ;    // 調用print()方法
        }
    };
      
    class Child extends Father{    // 定義繼承關係
        public void print(){    // 覆寫父類中的方法
            System.out.println("Child") ;
        }
         
    };
    public class Test4
    {
        public static void main(String args[])
        {
            Child s = new Child() ;
            s.fun() ;
        }
    };



Father中的this是個什麼鬼?爲何第10行打印出來是Child,第11行調用的print方法倒是Father中的。

以上就是這個問題自己了。 .net

回答: code

其實反編譯一下  看一下虛擬機的"彙編代碼"就很清楚了。。。

你的Father是這樣的。 繼承

class Father{       
        private void print()//這是私有方法
        {   
            System.out.println("Father") ;
        }
        public void fun()
        {   
            System.out.println(this);
            this.print() ;    // 調用print()方法
        }
    };




反編譯出來是這樣的:
public class Father {
  public Father();
    Code:
       0: aload_0
       1: invokespecial #1
()V
       4: return


  public void fun();
    Code:
       0: getstatic     #2
io/PrintStream;
       3: aload_0
       4: invokevirtual #5
n:(Ljava/lang/Object;)V
       7: aload_0
       8: invokespecial #6  //注意這裏是invokespecial
      11: return
}





而後我把Father改一下:(print方法改爲public)
public class Father {


public void print()//注意這裏是公共方法
     {   
         System.out.println("Father") ;
     }
     public void fun()
     {   
         System.out.println(this);
         this.print() ;    // 調用print()方法
     }
}

再反編譯一下:

public void print();
    Code:
       0: getstatic     #2
io/PrintStream;
       3: ldc           #3
       5: invokevirtual #4
n:(Ljava/lang/String;)V
       8: return


  public void fun();
    Code:
       0: getstatic     #2
io/PrintStream;
       3: aload_0
       4: invokevirtual #5
n:(Ljava/lang/Object;)V
       7: aload_0
       8: invokevirtual #6  //這裏是invokevirtual
      11: return
}
結論: 當你Father裏的print是private方法時,fun裏面使用invokespecial的。 當你Father裏的print是public方法時,fun裏面是用invokevirtual的。 invokespecial是調用私有方法(因此打印出來的是"Father"),invokevitual是調用實例方法(因此打印出來是"Child",這裏的實例,正如打印出來的this是child)
相關文章
相關標籤/搜索