import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class NullRobot {
public static void main(String[] args) {
//1
Robot r = newNullRobot();
if(Null.class.isInstance(r)){
// if(r instanceof Null){ //another way
System.out.println("[NullRobot]");
}
System.out.println(r.name());
List<Oper> l = r.ops();
for (Oper oper : l) {
System.out.println(oper.comm());
}
//2
Robot r2 = (Robot) new NullRobotProxyHandler().bind(null);
if(Null.class.isInstance(r2)){
System.out.println("[NullRobot]");
}
System.out.println(r2.name());
List<Oper> l2 = r2.ops();
for (Oper oper : l2) {
System.out.println(oper.comm());
}
}
public static Robot newNullRobot(){
return (Robot) Proxy.newProxyInstance(
NullRobot.class.getClassLoader(), //classLoader可以传入哪些?满足什么条件的classLoader可以被用来加载代理类
new Class[]{Robot.class, Null.class},
new NullRobotProxyHandler());
}
}
interface Null{}
class NullRobotProxyHandler implements InvocationHandler{
// Robot proxied =
class NRobot implements Robot
, Null //事实上,可以不继承Null接口,而只要Proxy.newProxyInstance()中的Class[]包含Null.class即可使instanceof判断为true
{
private String name = "NoneName";
@Override
public String name() {
// TODO Auto-generated method stub
return name;
}
@Override
public List<Oper> ops() {
// TODO Auto-generated method stub
return Collections.emptyList();
}
}
//===another bind way binding real obj with proxy
public Object bind(Object realObj){
realObj = new NRobot();
return (Robot) Proxy.newProxyInstance(
realObj.getClass().getClassLoader(),
realObj.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
return method.invoke(new NRobot(), args);
}
}
interface Oper{
String comm();
}
interface Robot{
String name();
List<Oper> ops();
}
class SnowRobot implements Robot{
private String name ;
public SnowRobot(String name){
this.name = name;
}
@Override
public String name() {
// TODO Auto-generated method stub
return name;
}
@Override
public List<Oper> ops() {
// TODO Auto-generated method stub
return Arrays.asList(new Oper(){
@Override
public String comm() {
// TODO Auto-generated method stub
return name +" do1";
}
},new Oper(){
@Override
public String comm() {
// TODO Auto-generated method stub
return name+" do2";
}
});
}
}