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表達式來實現了這個接口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM