// reflection/NullRobot.java // (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Using a dynamic proxy to create an Optional import java.lang.reflect.*; import java.util.*; import java.util.stream.*; import onjava.*; class NullRobotProxyHandler implements InvocationHandler { private String nullName; private Robot proxied = new NRobot(); NullRobotProxyHandler(Class type) { nullName = type.getSimpleName() + " NullRobot"; } private class NRobot implements Null, Robot { @Override public String name() { return nullName; } @Override public String model() { return nullName; } @Override public List operations() { return Collections.emptyList(); } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(proxied, args); } } public class NullRobot { public static Robot newNullRobot(Class type) { return (Robot)Proxy.newProxyInstance( NullRobot.class.getClassLoader(), new Class[]{ Null.class, Robot.class }, new NullRobotProxyHandler(type)); } public static void main(String[] args) { Stream.of( new SnowRobot("SnowBee"), newNullRobot(SnowRobot.class) ).forEach(Robot::test); } } /* Output: Robot name: SnowBee Robot model: SnowBot Series 11 SnowBee can shovel snow SnowBee shoveling snow SnowBee can chip ice SnowBee chipping ice SnowBee can clear the roof SnowBee clearing roof [Null Robot] Robot name: SnowRobot NullRobot Robot model: SnowRobot NullRobot */