背景
做Android的童鞋对Java里的几个作用域关键字肯定不陌生
public: 公开的,所有地方都可以访问
private: 私有的,只有当前类可以访问
protected: 继承的,当前类和子类可访问
default: 不包含任何作用域关键字,同一个包下可以访问
在这里想和大家讨论的就是这个default作用域,怎样才算同一个包下呢?
如何在包外访问default作用域的类或者方法
笔者写了一个简单的demo工程来验证这个问题,工程结构如下图
可以看到,这是一个标准的android工程结构,有app和test-lib两个module,app依赖test-lib。
test-lib下有两个类,代码如下,Test1类为public,但test2和test3方法是default作用域。Test2类为default,且test2方法也是default的。
在app里的MainActivity里尝试访问这些default作用域的成员
可以看到IDE报错了,报错信息如下
我们能访问这些default作用域的方法吗?有些童鞋可能会想到说用反射嘛,用反射确实可以访问。不用反射能做到吗?答案是可以的。我们在app module里建一个和Test1/Test2一样的包,如下图
在这个包名下新建TestProxy类,可以看到在TestProxy里可以成功地访问default作用域修饰的方法和类。编译是没有问题了,能正常运行吗?修改代码如下
运行日志如下,可以看到也能成功运行。
结论
是不是跟你理解的default作用域不太一样呢?所以在Android里default作用域的类或者方法在模块的包之下也是能够访问的,只需伪造一个和它一样的包名即可。笔者也尝试在Java里试了下,在Java里则会报错,如下图。都是用的java编译器,为啥现象不一样,有知道原因的同学欢迎留言告之^_^