作者最近研究框架底層代碼過程中感覺自己基礎不太牢固,於是寫了一點案例,以防日后忘記
接口類: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表達式來實現了這個接口。