方法的三个参数含义分别如下:
  loader:定义了代理类的ClassLoder;
  interfaces:代理类实现的接口列表
  h:调用处理器,也是我们上面定义的实现了InvocationHandler接口的类实例
  我们运行一下,看看我们的动态代理是否能正常工作。我这里运行后的输出为:
  说明我们的动态代理确实奏效了。
  上面我们已经简单提到过动态代理的原理,这里再简单的总结下:首先通过newProxyInstance方法获取代理类实例,而后我们便可以通过这个代理类实例调用代理类的方法,对代理类的方法的调用实际上都会调用中介类(调用处理器)的invoke方法,在invoke方法中我们调用委托类的相应方法,并且可以添加自己的处理逻辑。下面我们来看一下生成的代理类的代码究竟是怎样的。
  3. 动态代理类的源码分析
  通过运行Main,我们会得到一个名为“$Proxy”的class文件,这个文件即为动态生成的代理类,我们通过反编译来查看下这个代理类的源代码:
package com.sun.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements Sell {
//这5个Method对象分别代表equals()、toString()、ad()、sell()、hashCode()方法
private static Method m1;
private static Method m2;
private static Method m4;
private static Method m3;
private static Method m0;
//构造方法接收一个InvocationHandler对象为参数,这个对象是代理类的“直接委托类”(真正的委托类可以看做代理类的“间接委托类”)
public $Proxy0(InvocationHandler var1) throws  {
super(var1);
}
//对equals方法的调用实际上转为对super.h.invoke方法的调用,父类中的h即为我们在构造方法中传入的InvocationHandler对象,以下的toString()、sell()、ad()、hashCode()等方法同理
public final boolean equals(Object var1) throws  {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws  {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void ad() throws  {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void sell() throws  {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws  {
try {
return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
//这里完成Method对象的初始化(通过反射在运行时获得Method对象)
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]);
m4 = Class.forName("Sell").getMethod("ad", new Class[0]);
m3 = Class.forName("Sell").getMethod("sell", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
  我们可以看到,以上代码的逻辑十分简单,我们在注释中也做出了相关的说明。(以上代码中涉及到反射的使用,对于反射还不是很熟悉的小伙伴可以参考这里:Java核心技术点之反射)
  现在,我们已经了解了动态代理的使用,也搞清楚了它的实现原理,更进一步的话我们可以去了解动态代理类的生成过程,只需要去阅读newProxyInstance方法的源码即可,这个方法的逻辑也没有复杂的地方,这里不展开了。