【反射】Java反射的使用-调用方法

1,251 阅读2分钟

通过反射调用方法

获得pubblic和非public的方法

上一节中,我们使用getField()等获得了类的字段。同理,我们这里使用getMethod()

  • getMethod()只能获得public方法
  • getDeclaredMethod()可以获取所有方法,不管访问修饰符
  • getMethods()获取所有public方法
  • getDeclaredMethods()获取所有方法

举例:

public class Main {

    public static void main(String[] args) throws Exception {
        Person p = new Person();
        // 拿到大Class对象
        Class<? extends Person> pClass = p.getClass();
        // 获得方法
        Method eat = pClass.getDeclaredMethod("eat");
        eat.setAccessible(true);
        Method sleep = pClass.getMethod("sleep");
        eat.invoke(p);
        sleep.invoke(p);
    }
}

class Person {
    private void eat(){
        System.out.println("i can eat");
    }
    public void sleep(){
        System.out.println("i can sleep");
    }
}

分析

输出:
i can eat
i can sleep

该例子中,我们通过getDeclaredMethod()来获得私有方法,通过getMethod()来获得public方法。

调用上述方法后获得了Method对象。

然后再调用Method对象里的具体方法invoke()

可以看到我使用了setAccessible(true);,这个和获取字段同理,当你只是获得对象是可以使用getDelaredMethod(),但是你要使用invoke()调用它的方法,当且仅当修饰符为private你必须使用setAccessible(true);让其忽略修饰符。


上面我们演示了获取public和private方法,下面我们对其它类型的方法进行演示。

获得静态方法

当获得的是静态方法是,我们的invoke()方法第一个参数(执行对象)就应该为null, 静态方法是一加载就存在的,不需要实例即可运行。

执行下面的方法 sleep.invoke(null);

获得父类方法

获得父类方法与获得子类方法没有区别,直接通过方法名字。

有一种特殊情况,当子类与父类拥有同名方法,最终获得的是什么方法呢?

答案是子类的方法,因为优先获得的是本类的方法。

方法重载

如下,当我有多个重载方法,该怎么获得?

class Person {
    void sleep(String name){
        System.out.println("i can sleep");
    }
    void sleep(String name, String time){
        System.out.println("i can sleep");
    }
}

答案:通过getmethod()的参数,它的第二个参数为该方法需要传入的参数类型。


public class Main {

    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        // 获得方法
        Method sleep1 = personClass.getDeclaredMethod("sleep", String.class);
        Method sleep2 = personClass.getDeclaredMethod("sleep", String.class, String.class);
        sleep1.invoke(new Person(), "小红");
        sleep2.invoke(new Person(), "小胖", "一小时");
    }
}

Method对象

典型的Method对象方法:

  1. invoke():调用这个方法。
  2. getName():获取方法名。
  3. getParameterTypes():获取参数类型数组。
  4. getReturnType():获取返回值类型。
  5. getDeclaringClass():获取声明这个方法的类。
  6. getAnnotation(), 获得方法上的注解,要指定你要获得的注解类。
  7. isAnnotationPresent(), 判断是否有注解