原文地址:https://blog.youkuaiyun.com/zknxx/article/details/77919332
首先我们先定义一个接口:
- public interface PersonInter {
- String test(String str);
- }
- public class JdkProxySourceClass {
- public static void writeClassToDisk(String path){
- byte[] classFile = ProxyGenerator.generateProxyClass("$proxy4", new Class[]{PersonInter.class});
- FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(path);
- fos.write(classFile);
- fos.flush();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- if(fos != null){
- try {
- fos.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- @Test
- public void testGenerateProxyClass() {
- JdkProxySourceClass.writeClassToDisk("D:/$Proxy4.class");
- }
- }
OK接下来我们用反编译工具看一下生成的代理类源码:
- import com.zkn.newlearn.gof.proxyhandler.PersonInter;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.lang.reflect.UndeclaredThrowableException;
- public final class Proxy4 extends Proxy
- implements PersonInter
- {
- private static Method m1;
- private static Method m2;
- private static Method m3;
- private static Method m0;
- public Proxy4(InvocationHandler paramInvocationHandler)
- throws
- {
- super(paramInvocationHandler);
- }
- public final boolean equals(Object paramObject)
- throws
- {
- try
- {
- return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
- }
- catch (RuntimeException localRuntimeException)
- {
- throw localRuntimeException;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
- public final String toString()
- throws
- {
- try
- {
- return ((String)this.h.invoke(this, m2, null));
- }
- catch (RuntimeException localRuntimeException)
- {
- throw localRuntimeException;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
- public final String test(String paramString)
- throws
- {
- try
- {
- return ((String)this.h.invoke(this, m3, new Object[] { paramString }));
- }
- catch (RuntimeException localRuntimeException)
- {
- throw localRuntimeException;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
- public final int hashCode()
- throws
- {
- try
- {
- return ((Integer)this.h.invoke(this, m0, null)).intValue();
- }
- catch (RuntimeException localRuntimeException)
- {
- throw localRuntimeException;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
- static
- {
- try
- {
- m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
- m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
- m3 = Class.forName("com.zkn.newlearn.gof.proxyhandler.PersonInter").getMethod("test", new Class[] { Class.forName("java.lang.String") });
- m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
- return;
- }
- catch (NoSuchMethodException localNoSuchMethodException)
- {
- throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
- }
- catch (ClassNotFoundException localClassNotFoundException)
- {
- throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
- }
- }
- }
从反编译出来的源码中我们可以看到在静态代码块中得到了equals、toString、hashCode和PersonInter接口中test方法的Method对象。当我们调用PersonInter中的test方法的时候:
- public final String test(String paramString)
- throws
- {
- try
- {
- return ((String)this.h.invoke(this, m3, new Object[] { paramString }));
- }
- catch (RuntimeException localRuntimeException)
- {
- throw localRuntimeException;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
其实是调用了InvocationHandler中的invoke方法,并传入了之前获取到的对应的Method和参数。在这里也简单的说一下为什么JDK的动态代理只能代理接口不能代理类,请注意看我们所得到的代理类的源码,注意看这一句:public final class Proxy4 extends Proxy implements PersonInter。生成的代理类默认继承了Proxy这个类,而java中又是单继承的,所以这里只能代理接口,不能代理类了。就像枚举类,不能继承别的枚举类一样。