java多态的学习,overload和override的理解[英文]

找到了一个非常好的学习多态的网站(英文的),现在贴出来,可能有一些启发意义吧,大家有兴趣直接进网站看就好了,有问题欢迎评论。
https://programmingmitra.blogspot.com/2017/05/how-does-jvm-handle-method-overriding-internally.html
学习路线:

  1. Everything About ClassNotFoundException Vs NoClassDefFoundError
  2. Everything About Method Overloading Vs Method Overriding
  3. How Does JVM Handle Method Overloading and Overriding Internally

下面贴一部分我按照教程执行的结果。

> cmd: G:\Program Files\Java\jdk1.8.0_161\bin>javap -"verbose"
> D:\eclipse-workspace\JavaPuzzler\bin\OverridingInternalExample.class
> Classfile
> /D:/eclipse-workspace/JavaPuzzler/bin/OverridingInternalExample.class 
> Last modified 2018-8-3; size 961 bytes   MD5 checksum
> 16614163b3e084ea8bd3966c598c2694   Compiled from
> "OverridingInternalExample.java" public class
> OverridingInternalExample   minor version: 0   major version: 52  
> flags: ACC_PUBLIC, ACC_SUPER Constant pool:    #1 = Class             
> #2             // OverridingInternalExample    #2 = Utf8               OverridingInternalExample    #3 = Class              #4             //
> java/lang/Object    #4 = Utf8               java/lang/Object    #5 =
> Utf8               <init>    #6 = Utf8               ()V    #7 = Utf8 
> Code    #8 = Methodref          #3.#9          //
> java/lang/Object."<init>":()V    #9 = NameAndType        #5:#6        
> // "<init>":()V   #10 = Utf8               LineNumberTable   #11 =
> Utf8               LocalVariableTable   #12 = Utf8               this 
> #13 = Utf8               LOverridingInternalExample;   #14 = Utf8               main   #15 = Utf8               ([Ljava/lang/String;)V   #16 = Class  
> #17            // OverridingInternalExample$Mammal   #17 = Utf8               OverridingInternalExample$Mammal   #18 = Methodref          #16.#19   
> //
> OverridingInternalExample$Mammal."<init>":(LOverridingInternalExample$Mammal;LOverridingInternalExample$Mammal;)V
> #19 = NameAndType        #5:#20         // "<init>":(LOverridingInternalExample$Mammal;LOverridingInternalExample$Mammal;)V
> #20 = Utf8               (LOverridingInternalExample$Mammal;LOverridingInternalExample$Mammal;)V
> #21 = Methodref          #16.#22        // OverridingInternalExample$Mammal.speak:()V   #22 = NameAndType       
> #23:#6         // speak:()V   #23 = Utf8               speak   #24 = Class              #25            // OverridingInternalExample$Human  
> #25 = Utf8               OverridingInternalExample$Human   #26 = Methodref          #24.#27        //
> OverridingInternalExample$Human."<init>":(LOverridingInternalExample$Human;)V
> #27 = NameAndType        #5:#28         // "<init>":(LOverridingInternalExample$Human;)V   #28 = Utf8            
> (LOverridingInternalExample$Human;)V   #29 = Methodref         
> #24.#22        // OverridingInternalExample$Human.speak:()V   #30 = String             #31            // Hindi   #31 = Utf8              
> Hindi   #32 = Methodref          #24.#33        //
> OverridingInternalExample$Human.speak:(Ljava/lang/String;)V   #33 =
> NameAndType        #23:#34        // speak:(Ljava/lang/String;)V   #34
> = Utf8               (Ljava/lang/String;)V   #35 = Utf8               args   #36 = Utf8               [Ljava/lang/String;   #37 = Utf8      
> anyMammal   #38 = Utf8              
> LOverridingInternalExample$Mammal;   #39 = Utf8              
> humanMammal   #40 = Utf8               human   #41 = Utf8             
> LOverridingInternalExample$Human;   #42 = Utf8              
> SourceFile   #43 = Utf8               OverridingInternalExample.java  
> #44 = Utf8               InnerClasses   #45 = Utf8               Human   #46 = Utf8               Mammal {   public OverridingInternalExample();
>     descriptor: ()V
>     flags: ACC_PUBLIC
>     Code:
>       stack=1, locals=1, args_size=1
>          0: aload_0
>          1: invokespecial #8                  // Method java/lang/Object."<init>":()V
>          4: return
>       LineNumberTable:
>         line 1: 0
>       LocalVariableTable:
>         Start  Length  Slot  Name   Signature
>             0       5     0  this   LOverridingInternalExample;
> 
>   public static void main(java.lang.String[]);
>     descriptor: ([Ljava/lang/String;)V
>     flags: ACC_PUBLIC, ACC_STATIC
>     Code:
>       stack=4, locals=4, args_size=1
>          0: new           #16                 // class OverridingInternalExample$Mammal
>          3: dup
>          4: aconst_null
>          5: aconst_null
>          6: invokespecial #18                 // Method OverridingInternalExample$Mammal."<init>":(LOverridingInternalExample$Mammal;LOverridingInternalExample$Mammal;)V
>          9: astore_1
>         10: aload_1
>         11: invokevirtual #21                 // Method OverridingInternalExample$Mammal.speak:()V
>         14: new           #24                 // class OverridingInternalExample$Human
>         17: dup
>         18: aconst_null
>         19: invokespecial #26                 // Method OverridingInternalExample$Human."<init>":(LOverridingInternalExample$Human;)V
>         22: astore_2
>         23: aload_2
>         24: invokevirtual #21                 // Method OverridingInternalExample$Mammal.speak:()V
>         27: new           #24                 // class OverridingInternalExample$Human
>         30: dup
>         31: aconst_null
>         32: invokespecial #26                 // Method OverridingInternalExample$Human."<init>":(LOverridingInternalExample$Human;)V
>         35: astore_3
>         36: aload_3
>         37: invokevirtual #29                 // Method OverridingInternalExample$Human.speak:()V
>         40: aload_3
>         41: ldc           #30                 // String Hindi
>         43: invokevirtual #32                 // Method OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
>         46: return
>       LineNumberTable:
>         line 25: 0
>         line 26: 10
>         line 29: 14
>         line 30: 23
>         line 33: 27
>         line 34: 36
>         line 37: 40
>         line 39: 46
>       LocalVariableTable:
>         Start  Length  Slot  Name   Signature
>             0      47     0  args   [Ljava/lang/String;
>            10      37     1 anyMammal   LOverridingInternalExample$Mammal;
>            23      24     2 humanMammal   LOverridingInternalExample$Mammal;
>            36      11     3 human   LOverridingInternalExample$Human; } SourceFile: "OverridingInternalExample.java"

如果是在不想看英文,可以直接把下面的代码跑一下,我写了一些注释,应该也会有一些收获吧

public class OverridingInternalExample {
//reference:https://programmingmitra.blogspot.com/2017/05/how-does-jvm-handle-method-overriding-internally.html
    private static class Mammal {
        public void speak() { System.out.println("ohlllalalalalalaoaoaoa"); }
    }

    private static class Human extends Mammal {

        @Override
        public void speak() { System.out.println("Hello"); }

        // Valid overload of speak
        public void speak(String language) {
            if (language.equals("Hindi")) System.out.println("Namaste");
            else System.out.println("Hello");
        }

        @Override
        public String toString() { return "Human Class"; }

    }
//    cmd:
//    	G:\Program Files\Java\jdk1.8.0_161\bin>javap -"verbose" D:\eclipse-workspace\JavaPuzzler\bin\OverridingInternalExample.class
    //  Code below contains the output and and bytecode of the method calls
    public static void main(String[] args) {
        Mammal anyMammal = new Mammal();
        anyMammal.speak();  // Output - ohlllalalalalalaoaoaoa
        // 10: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

        Mammal humanMammal = new Human();
        humanMammal.speak(); // Output - Hello
        // 23: invokevirtual #4 // Method org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V

        Human human = new Human();
        human.speak(); // Output - Hello
        // 36: invokevirtual #7 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:()V

        human.speak("Hindi"); // Output - Namaste
        // 42: invokevirtual #9 // Method org/programming/mitra/exercises/OverridingInternalExample$Human.speak:(Ljava/lang/String;)V
    }
}

//首先可以看到Human.speak()和Human.speak:(Ljava/lang/String;)是两个不同的method,overload也就不难理解
//接下来看override,在编译阶段,可以看到anyMammal.speak();和invokevirtual #4编译成class之后都是一样的
//那么为什么它们还会调用不同的method呢,关键在于invokevirtual指令做的事情
//Operation invokevirtual accepts a pointer to method reference call ( #4 an index into the constant pool)
//And that method reference #4 again refers to a method name and Class reference
//观察以下内容:
/**
#4 = Methodref   #2.#27   // org/programming/mitra/exercises/OverridingInternalExample$Mammal.speak:()V
#2 = Class   #25   // org/programming/mitra/exercises/OverridingInternalExample$Mammal
#25 = Utf8   org/programming/mitra/exercises/OverridingInternalExample$Mammal
#27 = NameAndType   #35:#17   // speak:()V
#35 = Utf8   speak
#17 = Utf8
   ()V
*/
//也就是说,invokevirtual #4所指向的内容,又指向#2和#27,而#2和#27结合在一起指向(get a reference to)method 以及 method所在的class。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值