Java如何调用父类的父类的中的方法

来源:互联网 发布:js获取表单某个数据 编辑:程序博客网 时间:2024/06/05 02:33

1.可以用反射实现

2.可以用虚拟机级别的invokeddynamic实现(基于java1.7版本以及以上才可以)

代码如下:


/** * @(#)Text4.java * * * @author  * @version 1.00 2016/12/6 */import java.lang.invoke.MethodHandle;import java.lang.invoke.MethodType;import static java.lang.invoke.MethodHandles.lookup;public class Text4 {    class GrandFather{    void thinking(){    System.out.println("i am grandfather");    }    }        class Father extends GrandFather{    void thinking(){    System.out.println("i am father");    }    }        class son extends Father{    void thinking(){    try{    MethodType mt = MethodType.methodType(void.class);    MethodHandle mh = lookup().findSpecial(GrandFather.class,    "thinking", mt, getClass());    mh.invoke(this);    }catch(Throwable e){        }    }    }        public static void main(String[] args){    (new Text4().new son()).thinking();    }        }


对上述代码使用生成class字节码:


Classfile /E:/JAVAprojects/noMain/bin/noMain/son.class  Last modified 2016-12-6; size 1386 bytes  Compiled from "son.java"public class noMain.son extends noMain.Father  minor version: 0  major version: 51  flags: ACC_PUBLIC, ACC_SUPERConstant pool:   #1 = Class              #2             // noMain/son   #2 = Utf8               noMain/son   #3 = Class              #4             // noMain/Father   #4 = Utf8               noMain/Father   #5 = Utf8               <init>   #6 = Utf8               ()V   #7 = Utf8               Code   #8 = Methodref          #3.#9          // noMain/Father."<init>":()V   #9 = NameAndType        #5:#6          // "<init>":()V  #10 = Utf8               LineNumberTable  #11 = Utf8               LocalVariableTable  #12 = Utf8               this  #13 = Utf8               LnoMain/son;  #14 = Utf8               thinking  #15 = Methodref          #16.#18        // java/lang/Object.getClass:()Ljava/lang/Class;  #16 = Class              #17            // java/lang/Object  #17 = Utf8               java/lang/Object  #18 = NameAndType        #19:#20        // getClass:()Ljava/lang/Class;  #19 = Utf8               getClass  #20 = Utf8               ()Ljava/lang/Class;  #21 = Fieldref           #22.#24        // java/lang/Void.TYPE:Ljava/lang/Class;  #22 = Class              #23            // java/lang/Void  #23 = Utf8               java/lang/Void  #24 = NameAndType        #25:#26        // TYPE:Ljava/lang/Class;  #25 = Utf8               TYPE  #26 = Utf8               Ljava/lang/Class;  #27 = Methodref          #28.#30        // java/lang/invoke/MethodType.methodType:(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;  #28 = Class              #29            // java/lang/invoke/MethodType  #29 = Utf8               java/lang/invoke/MethodType  #30 = NameAndType        #31:#32        // methodType:(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;  #31 = Utf8               methodType  #32 = Utf8               (Ljava/lang/Class;)Ljava/lang/invoke/MethodType;  #33 = Methodref          #34.#36        // java/lang/invoke/MethodHandles.lookup:()Ljava/lang/invoke/MethodHandles$Lookup;  #34 = Class              #35            // java/lang/invoke/MethodHandles  #35 = Utf8               java/lang/invoke/MethodHandles  #36 = NameAndType        #37:#38        // lookup:()Ljava/lang/invoke/MethodHandles$Lookup;  #37 = Utf8               lookup  #38 = Utf8               ()Ljava/lang/invoke/MethodHandles$Lookup;  #39 = Class              #40            // noMain/GrandFather  #40 = Utf8               noMain/GrandFather  #41 = String             #14            // thinking  #42 = Methodref          #43.#45        // java/lang/invoke/MethodHandles$Lookup.findSpecial:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;  #43 = Class              #44            // java/lang/invoke/MethodHandles$Lookup  #44 = Utf8               java/lang/invoke/MethodHandles$Lookup  #45 = NameAndType        #46:#47        // findSpecial:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;  #46 = Utf8               findSpecial  #47 = Utf8               (Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;  #48 = Methodref          #49.#51        // java/lang/invoke/MethodHandle.invoke:(LnoMain/son;)V  #49 = Class              #50            // java/lang/invoke/MethodHandle  #50 = Utf8               java/lang/invoke/MethodHandle  #51 = NameAndType        #52:#53        // invoke:(LnoMain/son;)V  #52 = Utf8               invoke  #53 = Utf8               (LnoMain/son;)V  #54 = Class              #55            // java/lang/Throwable  #55 = Utf8               java/lang/Throwable  #56 = Utf8               a  #57 = Utf8               mt  #58 = Utf8               Ljava/lang/invoke/MethodType;  #59 = Utf8               mh  #60 = Utf8               Ljava/lang/invoke/MethodHandle;  #61 = Utf8               StackMapTable  #62 = Class              #63            // java/lang/Class  #63 = Utf8               java/lang/Class  #64 = Utf8               main  #65 = Utf8               ([Ljava/lang/String;)V  #66 = Methodref          #1.#9          // noMain/son."<init>":()V  #67 = Methodref          #1.#68         // noMain/son.thinking:()V  #68 = NameAndType        #14:#6         // thinking:()V  #69 = Utf8               args  #70 = Utf8               [Ljava/lang/String;  #71 = Utf8               SourceFile  #72 = Utf8               son.java  #73 = Utf8               InnerClasses  #74 = Utf8               Lookup{  public noMain.son();    descriptor: ()V    flags: ACC_PUBLIC    Code:      stack=1, locals=1, args_size=1         0: aload_0         1: invokespecial #8                  // Method noMain/Father."<init>":()V         4: return      LineNumberTable:        line 32: 0      LocalVariableTable:        Start  Length  Slot  Name   Signature            0       5     0  this   LnoMain/son;  void thinking();    descriptor: ()V    flags:    Code:      stack=5, locals=4, args_size=1         0: aload_0         1: invokevirtual #15                 // Method java/lang/Object.getClass:()Ljava/lang/Class;         4: astore_1         5: getstatic     #21                 // Field java/lang/Void.TYPE:Ljava/lang/Class;         8: invokestatic  #27                 // Method java/lang/invoke/MethodType.methodType:(Ljava/lang/Class;)Ljava/lang/invoke/MethodType;        11: astore_2        12: invokestatic  #33                 // Method java/lang/invoke/MethodHandles.lookup:()Ljava/lang/invoke/MethodHandles$Lookup;        15: ldc           #39                 // class noMain/GrandFather        17: ldc           #41                 // String thinking        19: aload_2        20: aload_1        21: invokevirtual #42                 // Method java/lang/invoke/MethodHandles$Lookup.findSpecial:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;        24: astore_3        25: aload_3        26: aload_0        27: invokevirtual #48                 // Method java/lang/invoke/MethodHandle.invoke:(LnoMain/son;)V        30: goto          34        33: astore_2        34: return      Exception table:         from    to  target type             5    30    33   Class java/lang/Throwable      LineNumberTable:        line 36: 0        line 38: 5        line 39: 12        line 40: 15        line 41: 17        line 40: 21        line 39: 24        line 43: 25        line 44: 30        line 47: 34      LocalVariableTable:        Start  Length  Slot  Name   Signature            0      35     0  this   LnoMain/son;            5      30     1     a   Ljava/lang/Class;           12      18     2    mt   Ljava/lang/invoke/MethodType;           25       5     3    mh   Ljava/lang/invoke/MethodHandle;      StackMapTable: number_of_entries = 2        frame_type = 255 /* full_frame */          offset_delta = 33          locals = [ class noMain/son, class java/lang/Class ]          stack = [ class java/lang/Throwable ]        frame_type = 0 /* same */  public static void main(java.lang.String[]);    descriptor: ([Ljava/lang/String;)V    flags: ACC_PUBLIC, ACC_STATIC    Code:      stack=2, locals=1, args_size=1         0: new           #1                  // class noMain/son         3: dup         4: invokespecial #66                 // Method "<init>":()V         7: invokevirtual #67                 // Method thinking:()V        10: return      LineNumberTable:        line 53: 0        line 55: 10      LocalVariableTable:        Start  Length  Slot  Name   Signature            0      11     0  args   [Ljava/lang/String;}SourceFile: "son.java"InnerClasses:     public static final #74= #43 of #34; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles


没有生成invokedynamic调用,应该是我的jvm配置出错,使得jvm栈帧的模式值调用了出栈的第一个实例使得输出答案为 i am father


虚拟机级别动态分配调用方法代码:


/** * @(#)StaticDispatch.java * * * @author  * @version 1.00 2016/12/6 */import java.lang.invoke.*;import java.lang.invoke.CallSite;import java.lang.invoke.ConstantCallSite;import java.lang.invoke.MethodHandle;import java.lang.invoke.MethodHandles;import java.lang.invoke.MethodType;import static java.lang.invoke.MethodHandles.lookup;public class StaticDispatch { static class ClassA{ public void println(String s){ System.out.println(s); } }        private static MethodHandle getPrintlnMH(Object recevier) throws Throwable{MethodType mt = MethodType.methodType(void.class,String.class);return lookup().findVirtual(recevier.getClass(),"println",mt).bindTo(recevier);}        public static void main(String[] args) throws Throwable{Object ob = System.currentTimeMillis() % 2 == 0 ? System.out : new ClassA();getPrintlnMH(ob).invokeExact("invoke println");     }    }


1 0