First, take a look at the following code:
Packageexample;Importjava.io.Serializable;Importjava.util.Arrays; Public classTest { Public Static InterfaceMyInterface {voidfoo ();} Public Static classBaseClassImplementsMyInterface, cloneable, Serializable {@Override Public voidfoo () {System.out.println ("Baseclass.foo"); } } Public Static classClass1extendsBaseClass {@Override Public voidfoo () {Super. Foo (); System.out.println ("Class1.foo"); } } Static classClass2extendsBaseClassImplementsMyInterface, cloneable, Serializable {@Override Public voidfoo () {Super. Foo (); System.out.println ("Class2.foo"); } } Public Static voidMain (string[] args) {showinterfacesfor (baseclass.class); Showinterfacesfor (Class1.class); Showinterfacesfor (Class2.class); } Private Static voidShowinterfacesfor (class<?>clazz) {System.out.printf ("%s--%s\n", Clazz, Arrays.tostring (clazz. getinterfaces ())); }}
The result of the output is:
class example. Test$baseclass--[interfaceinterfaceinterface java.io.Serializable] Class example. Test$class1--- []class example. Test$class2--[interfaceinterfaceinterface java.io.Serializable]
It can be seen from the results that although the parent class of the Class1 class implements the interface, it does not implement the interface again, so the interface to get the Class1 class directly through Java.lang.Class is an empty array.
Therefore, when implementing the agent, there will be problems, see the following code:
Packageexample;ImportJava.lang.reflect.InvocationHandler;ImportJava.lang.reflect.Method;ImportJava.lang.reflect.Proxy;Importexample. Test.baseclass;Importexample. Test.class1;Importexample. Test.class2; Public classTest2extendsTest { Public Static voidMain (string[] args) {MyInterface C1=NewClass1 (); MyInterface C2=NewClass2 (); //Note the order ...MyInterface Proxy2 =createproxy (C2); Proxy2.foo (); //This fails with an unchecked exceptionMyInterface Proxy1 =Createproxy (C1); Proxy1.foo (); } Private Static<T> T Createproxy (FinalT obj) { FinalInvocationhandler handler =NewInvocationhandler () {@Override Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {System.out.printf ("About-to-call%s () on%s\n", method. GetName (), obj); returnmethod.invoke (obj, args); } }; return(T) proxy.newproxyinstance (Obj.getclass (). getClassLoader (), obj. GetClass (). Getinterfaces (), handler);}}
The output is:
"Main" java.lang.ClassCastException: $Proxy 1 cannot is cast to example. Test$myinterface at example. Test2.main (Test2.java:23)
You can see that when CLASS1 implements an interface proxy, it will report an exception.
Therefore, this is not a mistake, it is likely that the author Josh Bloch to facilitate the implementation of the agent and carefully designed.
Reference: Http://stackoverflow.com/questions/2165204/why-does-linkedhashsete-extend-hashsete-and-implement-sete
Since ArrayList inherits from Abstractlist Abstract class, and Abstractlist has implemented the list interface, why should the ArrayList class implement the list interface again?