java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式

Posted 萌萌哒的陈C酱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式相关的知识,希望对你有一定的参考价值。

 作者最近研究框架底层代码过程中感觉自己基础不太牢固,于是写了一点案例,以防日后忘记

 

接口类:Animals

1 public interface Animals {
2 
3     public void eat();
4 }
package cn.chenc.study.entity;

public interface InterfaceFactory {

    public String show(int i);
    
}

 

 

 

实体类:Person

package cn.chenc.study.entity;

import java.lang.reflect.Proxy;

public class Person implements Animals {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name=‘" + name + ‘‘‘ +
                ", age=" + age +
                ‘}‘;
    }

    public void show(String name,int age){
        System.out.println("name="+name+",age="+age);
    }

    public void eat(){
        System.out.println("人用餐具吃饭");


    }

    public void run(String s,int i){
        System.out.println("人用"+i+"只"+s+"走路");
    }


}

 

 

测试类:

package cn.chenc.study;

import cn.chenc.study.entity.Animals;
import cn.chenc.study.entity.InterfaceFactory;
import cn.chenc.study.entity.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class Demo1 {

    public static void main(String[] args) throws Exception{
        //调用toString
        Class clazz=Class.forName("cn.chenc.study.entity.Person");
        Method method=clazz.getMethod("toString");
        Constructor constructor=clazz.getConstructor(String.class,int.class);
        Object object=constructor.newInstance("secret",21);
        System.out.println(method.invoke(object,null));
        //调用show
        method=clazz.getMethod("show",String.class,int.class);

        method.invoke(object,"chen",19);

        //接口测试,person实现animals
        Class[] interfaces= clazz.getInterfaces();
        Class childClass=interfaces.getClass();
        Class inter=interfaces[0];

        method=inter.getMethod("eat");
        method.invoke(object);

        //代理测试
        Animals proxy = (Animals) Proxy.newProxyInstance(clazz.getClassLoader(), interfaces, (proxy1, method1, args_temp) -> {
            Object result = method1.invoke(object, args_temp);
            return result;
        });
        proxy.run("脚", 2);



        //lanmbda 函数式接口
        lambdaTest((a) -> {
            //    return new Person();
            return String.valueOf(a);
        });

    }

    public static void lambdaTest(InterfaceFactory interfaceFactory){
        System.out.println(interfaceFactory.show(1));

    }
}

总结:

函数式接口:。

InterfaceFactory interfaceFactory=
(a) -> {
            //    return new Person();
            return String.valueOf(a);
        };
实际上这里是创建了一个匿名的子类对象,并且实现了show方法,show方法的是参数int类型,返回值String类型。函数式接口有且只有一个抽象方法,可以有很多个非抽象方法,比如静态方法。在接口中,
变量默认是puublic static final
方法默认是public abstract

前三种都是通过指定className和method方法来实现的调用,如果进行传参还需要getMethod,感觉还是挺不灵活的。

如果使用动态代理的话,就可以直接使用接口来调用,并且还能实现方法的增强。

Proxy类就是用来创建一个代理对象的类,我们最常用的是newProxyInstance方法。

InvocationHandler也是动态代理一个很重要的接口,里面有一个invoke方法,我这里是使用了lambda表达式来实现了这个接口。

以上是关于java反射-Method中的invoke方法的用法-以及函数式接口和lambda表达式的主要内容,如果未能解决你的问题,请参考以下文章

java反射机制之Method invoke执行调用方法例子

反射中的一个问题点:利用Method执行main方法特殊的地方

java反射的invoke方法

JAVA 反射之Method

method.invoke(...)反射点

Java反射机制获取set()方法 并且为set()方法传值