下表为Java访问控制符的含义和使用情况
| 类内部 | 本包 | 子类 | 外部包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
通过此表一目了然。
- public:Java语言中访问限制最宽的修饰符,一般称之为“公共的”。被其修饰的类、属性以及方法不仅可以跨类访问,而且允许跨包(package)访问。
- private:Java语言中对访问权限限制的最窄的修饰符,一般称之为“私有的”。被其修饰的类、属性以及方法只能被该类的对象访问,其子类不能访问,更不能允许跨包访问。
- protected:介于public 和 private 之间的一种访问修饰符,一般称之为“保护形”。被其修饰的类、属性以及方法只能被类本身的方法及子类访问,即使子类在不同的包中也可以访问。
- default:即不加任何访问修饰符,通常称为“默认访问模式“。该模式下,只允许在同一个包中进行访问。
相信public、protected、private大家都特别清楚,现在主要通过反射机制来验证下default。
先定义一个抽象类FourModifier,如下:
package com.common.fourmodifier;
//没有访问控制符修饰,
abstract class FourModifier {
private int age;
//default
String name;
}
然后定义一个SubFourModifier类继承FourModifier,并位于同一个package下,如下
package com.common.fourmodifier;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
//与父类在同一个package下
public class SubFourModifier extends FourModifier{
public static void main(String[] args) {
System.out.println("类修饰符:"+Modifier.toString(FourModifier.class.getModifiers()));
//反射获取所有声明成员变量(包括私有)
Field[] field = FourModifier.class.getDeclaredFields();
for(Field f:field){
if("".equals(Modifier.toString(f.getModifiers()))){
System.out.println("field:default "+f.getName()); //缺省情况下默认为default,所以获取修饰符为""
}else{
System.out.println("field:"+Modifier.toString(f.getModifiers())+" "+f.getName());
}
}
}
}
运行结果如下:
或许现在你会觉得可以在子类访问分类的default成员变量,错!
那么现在试试新建一个package,并在此package下新建一个类继承FourModifier,如下:
由于粘代码不能显示错误,直接上图,你会发现直接编译报错,因为FourModifier类没有声明访问控制类型,默认为default,而default只能在同一个package下访问类成员变量,无论是不是子类。
若FourModifier类加上public修饰符,上述程序正常运行,结果如下:
每日一语:多思考多总结。