Method 是否能调用的判断

首先让我们看一下java中的动态代理,我也是从中受到启动的
定义一个接口

package com.TestProxy;
public interface IFruit {
    void eat(String i);
    void shape(String i);
}
接着有个实现类
package com.TestProxy;

public class Apple implements IFruit {
    public void eat(String i) {
        // TODO Auto-generated method stub
        System.out.println("吃了一个苹果");
    }

    public void shape(String i) {
        // TODO Auto-generated method stub

    }
}

接着有一个代理类

package com.TestProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyProxy implements InvocationHandler {
Apple apple = new Apple();
    public static void main(String[] args){
       MyProxy myProxy = new MyProxy(new Apple());
        ((IFruit)  myProxy.getProxy()).eat("1");
      /*  Apple apple = new Apple();
        Method[] methods =IFruit.class.getDeclaredMethods();
        for (Method method:methods){
            try {
                method.invoke(new front(),new Object[]{"1"});
                System.out.println(method);
            }catch (Exception e){
                e.printStackTrace();
            }


        }
*/
    }

    Object target;
    public MyProxy(Object target){
        this.target=target;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("start");
        System.out.println(method); //注意这里打印的方法所属的类
        method.invoke(apple,args); //——————注意这里
        // 此处为方法实际执行的地方,当然你也可以根本就不执行此方法,mybatis就是根本不管这里的方法,他需要的只是方法名,用方法名来找到对应的sql语句,参数,返回值的信息
        Object result=method.invoke(target, args);

        return result;
    }
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{IFruit.class},this);
    }

}

//我们知道动态代理,在调用接口类的时候其实,调用invoke方法而其实在invoke方法中method 在我们抓为接口的时候其实穿入的方法是接口的方法,而在invoke中闯入的是实现类,这从侧面说明, method.invoke(apple,args)中的第一个参数使用instanceof判断是否能调用成功,

如果你自己自定义一个类而不实现IFruit接口,但是有相同的方法 在动态代理的invoke方法里面使用 method.invoke(otherObject,args);将会报错;例如

有这样一个类

package com.TestProxy;

public class front {
    public void eat(String i) {
        // TODO Auto-generated method stub
        System.out.println("吃了一个苹果");
    }
    public void shape(String i) {
        // TODO Auto-generated method stub

    }
}

在上述方法中使用 method.invoke(new front(),args);将会报错

可见 method.invoke方法是否能掉用成功,需要判定第一个参数是否是方法所属类的子类或原本的类(即使用instanceof判断)

猜你喜欢

转载自blog.csdn.net/qq_32459653/article/details/81173271