美文网首页
java.lang.reflect.Method类中的一些方法说

java.lang.reflect.Method类中的一些方法说

作者: 阿福德 | 来源:发表于2019-08-01 16:03 被阅读0次

getModifiers()

先看jdk中的方法说明java.lang.reflect.Method:

   @Override
   public int getModifiers() {
       return modifiers;
   }

我们看到有一个@Override注解
我们其看父类:java.lang.reflect.Executable

    /**
     * Returns the Java language {@linkplain Modifier modifiers} for
     * the executable represented by this object.
     */
    public abstract int getModifiers();

从注释可以看出,这个方法返回的是int类型的方法上的修复符号
看一个测试

public class Modle {
    String a;
    private String b;
    protected  String c;
    public String d;
    final String e="";
    static String f;
    public static String g;
    public static final String h="";

    String geta(){return "";}
    private void getb(){}
    protected  void getc() {}
    static void getd() {}
    public static final void gete(){}
}
import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestMethod {
    @Test
    public void test() {
        Class clazz = Modle.class;
        for (Field f : clazz.getDeclaredFields()) {
            System.out.println("field:" + f.getName() + ":" + f.getModifiers());
        }
        for (Method m : clazz.getDeclaredMethods()) {
            System.out.println("method:" + m.getName() + ":" + m.getModifiers());
        }
    }
}

field:a:0
field:b:2
field:c:4
field:d:1
field:e:16
field:f:8
field:g:9
field:h:25
method:getb:2
method:getc:4
method:geta:0
method:getd:8
method:gete:25

送上面的结果可以看到,不适用任何修饰符, getModifiers()返回0
public:1
private:2
protect: 4
static:8
final:16
public + static + final = 1 + 8 + 16 = 15

isBridge()

先看jdk中的方法说明java.lang.reflect.Method:

    /**
     * Returns {@code true} if this method is a bridge
     * method; returns {@code false} otherwise.
     *
     * @return true if and only if this method is a bridge
     * method as defined by the Java Language Specification.
     * @since 1.5
     */
    public boolean isBridge() {
        return (getModifiers() & Modifier.BRIDGE) != 0;
    }

上面注解说道brigeMethod(桥接方法), 啥是桥接方法:
原来jdk5引入了泛型,但是泛型在编译后又是没有的,即泛型擦除。
这样在编译的时候,就引入了桥接方法,举个栗子:

public class Parent<T> {
    public void process(T t){
        System.out.println("parent:"+t);
    }
    public void print(Object obj){
        System.out.println("parent:"+obj);
    }
}
public class Son extends Parent<String> {

    public void process(String str) {
        System.out.println("son:"+str);
    }
    public void print(String obj){
        System.out.println("son:"+obj);
    }
    public static void main(String[] args) {
        Parent son = new Son();
        son.process("son");
        son.print("son");
        for(Method method : Son.class.getDeclaredMethods()) {
            System.out.println(method.getName()+"("+method.getParameterTypes()[0]+"), isBridge:" +method.isBridge());
        }
    }
}

执行结果:

son:son
parent:son
main(class [Ljava.lang.String;), isBridge:false
print(class java.lang.String), isBridge:false
process(class java.lang.String), isBridge:false
process(class java.lang.Object), isBridge:true
第一个执行了子类的方法,第二个执行了父类的方法。
按道理说泛型类型擦除了,父类的两个方法中的参数类型应该都是Object
我们看看Son的字节码

$ javap -c Son.class
Compiled from "Son.java"
public class Son extends Parent<java.lang.String> {
  public Son();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method Parent."<init>":()V
       4: return

  public void process(java.lang.String);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      10: ldc           #5                  // String son:
      12: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: aload_1
      16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      25: return

  public void print(java.lang.String);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: new           #3                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      10: ldc           #5                  // String son:
      12: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: aload_1
      16: invokevirtual #6                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #7                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: invokevirtual #8                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      25: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #9                  // class Son
       3: dup
       4: invokespecial #10                 // Method "<init>":()V
       7: astore_1
       8: aload_1
       9: ldc           #11                 // String son
      11: invokevirtual #12                 // Method Parent.process:(Ljava/lang/Object;)V
      14: aload_1
      15: ldc           #11                 // String son
      17: invokevirtual #13                 // Method Parent.print:(Ljava/lang/Object;)V
      20: return

  public void process(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #14                 // class java/lang/String
       5: invokevirtual #15                 // Method process:(Ljava/lang/String;)V
       8: return
}

从上面字节码来看, 最后一个接收Object类型的process方法,在第5步调用了接收String类型的process方法。这个接收Object类型参数的process就是bridge方法。
在子类中没有接收Object类型的print方法,因为子类复写了父类的print方法。

isVarArgs() 是否可变参数

总结:

我们在工作中,使用到,或者了解到的java只是其冰山一角,下次看谁再说精通java。

相关文章

  • java.lang.reflect.Method类中的一些方法说

    getModifiers() 先看jdk中的方法说明java.lang.reflect.Method: 我们看到有...

  • 关于数学

    Number & Math 类方法 下面的表中列出的是 Number & Math 类常用的一些方法: 序号方法与...

  • Python 类的一些特殊方法

    Python 类的一些特殊方法 Python 的类中存在一些特殊的方法,使得我们自己构造的类能够更加清晰并支持某些...

  • 01.11 - 类的方法–对象方法

    class 类名: 类中的属性 类中的方法 类中的方法 声明在类中的函数就是方法 类中的方法包括:对象方法(实例方...

  • DAY11

    学习了API中String类,数学类,正则表达式,日期类中的一些主要的方法

  • 对象方法

    class 类名: 类中的属性 类中的方法 1.类中的方法 声明在类中的函数就是方法类中的方法包括: 对象方...

  • python之抽象基类

    python之抽象基类 抽象基类,在这个类中定义一些方法,所有继承这个类的类必须实现这个方法,并且这个类不能被实例...

  • Android开发规范

    一些约定 类中public方法在前,private在后,所有不对外的方法,变量全部使用private修饰符。类中p...

  • Android App开发规范

    一些约定 类中public方法在前,private在后,所有不对外的方法,变量全部使用private修饰符。类中p...

  • objc中的类方法和实例方法有什么本质区别和联系?

    类方法:类方法是属于类对象的类方法只能通过类对象调用类方法中的self是类对象类方法可以调用其他的类方法类方法中不...

网友评论

      本文标题:java.lang.reflect.Method类中的一些方法说

      本文链接:https://www.haomeiwen.com/subject/oggqdctx.html