* @Author: chenfuxian
* @Date: 2020/7/27 22:22
* 对Collection接口进行代理,以前的remove(Object obj)方法是删除集合中第一次出现的元素
* (比如集合中有多个“abc”,调用remove(“abc”)后只会删除一个元素)。代理后,要求在调用remove(Object obj)方法后,
* 能够删除集合中所有匹配的元素。Collectionde 的toString方法。【动态代理】
*/
public class Test04 {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("abc");
collection.add("bac");
collection.add("abc");
collection.add("cba");
collection.add("abc");
collection.add("abc");
System.out.println(collection);
Class<? extends Collection> collectionClass = collection.getClass();
Collection proxy = (Collection)Proxy.newProxyInstance(collectionClass.getClassLoader(), collectionClass.getInterfaces(), new InvocationHandler() {
/*参数1:ClassLoader loader 被代理对象的类加载器
参数2:Class<?>[] interfaces 被代理对象的要实现的接口
参数3:InvocationHandler h (接口)执行处理类。Proxy的接口,用于new代理对象。
返回值: 代理对象。proxy
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/* 调用代理类的任何方法,此方法都会执行
- 参数1:代理对象(慎用)。invoke方法内用会进入死循环。
- 参数2:当前执行的方法。指代理proxy调用的方法。
- 参数3:当前执行的方法运行时传递过来的参数。实参。
- 返回值:当前方法执行的返回值*/
//public Object invoke(Object obj, Object... args),可变参数可以传入数组args。
//返回值为超类Object,避免代理proxy调用不同方法的返回值类型不一样而报错。
Object res = method.invoke(collection,args);
//if中为增强方法,可用于某个方法的增强;判断方法是否为remove,iterator删除集合中所有"abc"元素
if (method.getName().equals("remove")) {
Iterator<String> it = collection.iterator();
while (it.hasNext()) {
String next = (String) it.next();
if (next.equals(args[0])){
it.remove();
}
}
}
return res;
}
});
boolean b = proxy.remove("abc");
System.out.println(collection);
String s = proxy.toString();
System.out.println(s);
}
}