正在学习core java的第六章中的proxy这一小节,感觉非常有意思,下面是书中举例的代码
package proxy;
import java.lang.reflect.*;
import java.util.*;
public class ProxyTest
{
public static void main(String[] args)
{
Object[] elements = new Object[1000];
// fill elements with proxies for the integers 1 ... 1000
for (int i = 0; i < elements.length; i++)
{
Integer value = i + 1;
InvocationHandler handler = new TraceHandler(value);
Object proxy = Proxy.newProxyInstance(null, new Class[] { Comparable.class } , handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;
// search for the key
int result = Arrays.binarySearch(elements, key);
// print match if found
if (result >= 0) System.out.println(elements[result]);
}
}
/**
* An invocation handler that prints out the method name and parameters, then
* invokes the original method
*/
class TraceHandler implements InvocationHandler
{
private Object target;
/**
* Constructs a TraceHandler
* @param t the implicit parameter of the method call
*/
public TraceHandler(Object t)
{
target = t;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
{
// print implicit argument
System.out.print(target);
// print method name
System.out.print("." + m.getName() + "(");
// print explicit arguments
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
System.out.print(args[i]);
if (i < args.length - 1) System.out.print(", ");
}
}
System.out.println(")");
// invoke actual method
return m.invoke(target, args);
}
}
我测试了代码后,突然想到如果不用包装类Integer,直接用自定义类,然后实现接口Comparable,能不能也可以用二分查找函数来实现代理调用,下面是我的代码。
package wwydr.chapter6;/*
import java.lang.reflect.*;
import java.util.*;
public class ProxyTest
{
public static void main(String[] args)
{
Object[] elements = new Object[1000];
// fill elements with proxies for the integers 1 ... 1000
for (int i = 0; i < elements.length; i++)
{
// Integer value = i + 1;
int rAge = new Random().nextInt(65) + 1;
Comparable value = new Employee32(rAge);
InvocationHandler handler = new TraceHandler(value);
ClassLoader loader=value.getClass().getClassLoader();
Class [] interfaces=value.getClass().getInterfaces();
Object proxy = Proxy.newProxyInstance(loader, interfaces , handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(65) + 1;
// search for the key
//binarySearch函数的返回值:
// 如果key在数组中,则返回搜索值的索引;否则返回-1或者”-“(插入点)。插入点是索引键将要插入数组的那一点,即第一个大于该键的元素索引。
int result = Arrays.binarySearch(elements, key);
// print match if found
if (result >= 0) System.out.println(elements[result]);
}
}
/**
* An invocation handler that prints out the method name and parameters, then
* invokes the original method
*/
class TraceHandler implements InvocationHandler
{
private Object target;
/**
* Constructs a TraceHandler
* @param t the implicit parameter of the method call
*/
public TraceHandler(Object t)
{
target = t;
}
@Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
{
// print implicit argument
System.out.print(target);
// print method name
System.out.print("^" + m.getName() + "(");
// print explicit arguments
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
System.out.print(args[i]);
if (i < args.length - 1) {
System.out.print(", ");
}
}
}
System.out.println(")");
try {
return m.invoke(target, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}
}
class Employee32 implements Comparable<Employee32>
{
private int age;
@Override
public int compareTo(Employee32 o) {
return this.age - o.age;
}
public Employee32(int age) {
this.age = age;
}
}
相像是美好的,结果却很残酷,编译没有问题,运行时报错如下:
wwydr.chapter6.Employee32@5cad8086^compareTo(65)
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to wwydr.chapter6.Employee32
at wwydr.chapter6.Employee32.compareTo(ProxyTest.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at wwydr.chapter6.TraceHandler.invoke(ProxyTest.java:88)
at com.sun.proxy.$Proxy0.compareTo(Unknown Source)
at java.util.Arrays.binarySearch0(Arrays.java:2439)
at java.util.Arrays.binarySearch(Arrays.java:2379)
at wwydr.chapter6.ProxyTest.main(ProxyTest.java:41)
错误出现在这一句:return m.invoke(target, args);
args参数是Integer类型,target参数是Employee32类型,和我相像的两个都是Employee32类型不一致,我查了好多资料,居然都没有合适的解决办法,只能来此向各位请教,这究竟是什么原因,我该如何来解决这个问题.