java代理的一个小坑

java代理的一个小坑

工作中一个业务逻辑需要用到java的代理,java代理需要实现InvocationHandler接口,并覆写invoke方法:

public class TestInvocationHandler : implements InvocationHandler {
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		...
	}
}

这都是通用写法,不再赘述。但是在运行过程中碰到一个报错:

Class com.xxx.handler.TestInvocationHandler can not access a member of class com.xxx.biz.TestAPI with modifiers "public abstract"

搜索也没找到解决办法,最后在startoverflow找到一个规避办法,在invoke方法中增加

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		method.setAccessible(true);
		...
	}

问题还真解决了!不过这个答案也启发了我继续探索这个问题的原因。
在代码中TestInvocationHandler在handler package下,而业务接口定义在biz package下,而我发现定义接口时,接口的访问域没填,是java语言默认值。

interface TestAPI {
}

设置interface的访问域为public,不需要method.setAccessible(true);,问题同样也解决了!

public interface TestAPI {
}

但为什么呢?继续查找资料,参考深入java(类)接口默认修饰符问题,在interface没指定修饰符的情况下默认是frendly,包内的任何类都可以访问它,而包外的任何类都不能访问它(包括包外继承了此类的子类)。


所以handler包里TestInvocationHandler不能访问biz包里的TestAPI就不奇怪了。奇怪的是编译过程没有报错。
再深入去想,java的代理机制就是在运行时才决定接口的具体实现,不是在编译过程中确定的。整个过程也就不奇怪了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值