Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There is another reason; consider the following java program:-</p> <pre><code>package example; import java.io.Serializable; import java.util.Arrays; public class Test { public static interface MyInterface { void foo(); } public static class BaseClass implements MyInterface, Cloneable, Serializable { @Override public void foo() { System.out.println("BaseClass.foo"); } } public static class Class1 extends BaseClass { @Override public void foo() { super.foo(); System.out.println("Class1.foo"); } } static class Class2 extends BaseClass implements MyInterface, Cloneable, Serializable { @Override public void foo() { super.foo(); System.out.println("Class2.foo"); } } public static void main(String[] args) { showInterfacesFor(BaseClass.class); showInterfacesFor(Class1.class); showInterfacesFor(Class2.class); } private static void showInterfacesFor(Class&lt;?&gt; clazz) { System.out.printf("%s --&gt; %s\n", clazz, Arrays.toString(clazz .getInterfaces())); } } </code></pre> <p>Which outputs the following text (java 6u16):</p> <pre><code>class example.Test$BaseClass --&gt; [interface example.Test$MyInterface, interface java.lang.Cloneable, interface java.io.Serializable] class example.Test$Class1 --&gt; [] class example.Test$Class2 --&gt; [interface example.Test$MyInterface, interface java.lang.Cloneable, interface java.io.Serializable] </code></pre> <p>Notice how Class1 does not have explicit interfaces defined, so the Class#getInterfaces() does not include those interfaces, whereas Class2 does. The use of this only becomes clear in this program:- </p> <pre><code>package example; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import example.Test.BaseClass; import example.Test.Class1; import example.Test.Class2; public class Test2 extends Test { public static void main(String[] args) { MyInterface c1 = new Class1(); MyInterface c2 = new Class2(); // Note the order... MyInterface proxy2 = createProxy(c2); proxy2.foo(); // This fails with an unchecked exception MyInterface proxy1 = createProxy(c1); proxy1.foo(); } private static &lt;T&gt; T createProxy(final T obj) { final InvocationHandler handler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.printf("About to call %s() on %s\n", method .getName(), obj); return method.invoke(obj, args); } }; return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), handler); } } </code></pre> <p>Which outputs:-</p> <pre><code>About to call foo() on example.Test$Class2@578ceb BaseClass.foo Class2.foo Exception in thread "main" java.lang.ClassCastException: $Proxy1 cannot be cast to example.Test$MyInterface at example.Test2.main(Test2.java:23) </code></pre> <p>While Class1 does implicitly implement MyInterface, but the created proxy does not.</p> <p>Hence if we wanted to create a dynamic proxy which implements all interfaces for an object which has implicit interface inheritance then the only way to do it generically would be to walk the superclasses all the way back to java.lang.Object, as well as walking all the implemented interfaces and their superclasses (remember Java supports multiple interface inheritance), which doesn't sound very efficient, while it is much easier (and faster) to explicitly name interfaces as I suppose they are set in at compile time.</p> <p>So what uses reflection &amp; proxies? RMI for one... </p> <p>Therefore, yes it is a convenience, but no it is certainly not redundant: remember that these classes were carefully designed and implemented by Josh Bloch, so I suspect that they were explicitly programmed this way so that proxied network stubs and skeletons work as they do.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload