Javaのオブジェクトはメッセージではない(追記:?)

このコードが通らないので。

import java.lang.reflect.*;

interface A {
    public String a();
}

class A2 {
    public String a(){return "A2";}
}

public class Fuga {
    public static void main(String[] args) throws Throwable{
        final A2 a2 = new A2();
        
        Class<?>[] interfaces = {A.class};
        A proxyA = (A)Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces,
                new InvocationHandler(){
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        return method.invoke(a2, args);
                    }
        });
        
        System.out.println(proxyA.a()); //throws java.lang.IllegalArgumentException: object is not an instance of declaring class
    }
}

こうすれば通る

import java.lang.reflect.*;

interface A {
    public String a();
}

class A2 {
    public String a(){return "A2";}
}

public class Fuga {
    public static void main(String[] args) throws Throwable{
        final A2 a2 = new A2();
        
        Class<?>[] interfaces = {A.class};
        A proxyA = (A)Proxy.newProxyInstance(
                Thread.currentThread().getContextClassLoader(), interfaces,
                new InvocationHandler(){
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        try {
                            return method.invoke(a2, args);
                        } catch (IllegalArgumentException e) {
                            return a2.getClass().getDeclaredMethod(
                                    method.getName(), method.getParameterTypes())
                                    .invoke(a2, args);
                        }
                    }
        });
        
        System.out.println(proxyA.a()); //prints A2
    }
}

ついき

このエントリを書いた時点では、メッセージは文字列って捉えてたけど、Javaの場合は型情報を含んだメソッドオブジェクトをメッセージとしてやりとりすると考えても良さそう、というのがコメント欄のやりとりです。id:Nagiseのご指摘感謝。