默认情况下枚举中变量的访问级别是什么
最近我遇到了以下代码:
enum Animals { DOG("woof"), CAT("meow"), FISH("burble"); String sound; Animals(String s) { sound = s; } } class TestEnum { static Animals a; public static void main(String[] args) { System.out.println(a.DOG.sound + " " + a.FISH.sound);//Expected compilation failure } }
我希望代码无法编译因为这个a.DOG.sound
部分。 但令我惊讶的是它没有。 我四处搜索,包括官方文档,以找出访问级别,但一无所获。 是公开的还是默认的 ?
枚举中手动声明的字段的隐式访问级别是package-private ,与普通类中的完全相同。 因此,当且仅当Animals
和TestEnum
位于同一个包中时,才能访问您的sound
场。
我试图在JLS中为此找到一个可靠的引用,但不幸的是,枚举规则遍布整个地方,被指定为普通类规则的例外,因此规则必须从各个部分组合。 JLS§6.6.1确定可访问性说:
只有在类型可访问且声明成员或构造函数允许访问时,才可访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:
如果成员或构造函数声明为
public
,则允许访问。缺少访问修饰符的接口的所有成员都是隐式
public
。否则,如果成员或构造函数被声明为
protected
,则只有在满足以下条件之一时才允许访问:
从包含声明
protected
成员或构造函数的类的包中发生对成员或构造函数的访问。访问是正确的,如§6.6.2中所述。
否则,如果使用包访问声明成员或构造函数,则仅当从声明类型的包中进行访问时才允许访问。
声明没有访问修饰符的类成员或构造函数隐式具有包访问权限。
否则,成员或构造函数被声明为private ,并且当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问。
这意味着类类型( class
和enum
)获得成员隐式具有包访问权限的规则,而接口类型( interface
和@interface
)获得成员隐式公开的规则。
从上面可以看出,“类成员”在其“类”的定义中包含枚举,但确实如此。 由于它们的广泛重叠,JLS组在许多地方枚举了类(并且注释类型同样与接口一起分组)。 JLS§8.9枚举类型说“枚举声明指定一种新的枚举类型,一种特殊的类类型”; 和JLS§8.2class级成员明确指出,“class级成员”一词是指“class级类型”的成员。
但是,枚举确实有两个关于成员可访问性的特殊规则,这些规则未包含在上面引用的部分中:
-
枚举常量本身(在您的示例中为
DOG
,CAT
和FISH
)可能没有任何显式访问修饰符( JLS§8.9.1 ),并且始终是枚举类型的public static final
字段( JLS§8.9.3 ) 。 -
枚举构造函数必须是私有的(以防止人们创建额外的常量)并且是隐式私有的( JLS§8.9.2 )。
除了这两个例外,普通类的访问规则适用于枚举。 如果您的Animals
枚举是public
,它及其所有常量都可以在包外访问,但sound
场是包私有的,除非您明确public
声明,否则无法在包外访问。
如果可以导入
enum
,则可以访问enum
常量
如果enum
在package
外可访问(特别是声明为public
),则它的元素也是可访问的,如果没有指定修饰符,它只能在package
内访问。 默认情况下,如果enum
可访问,则可以访问enum
常量,这意味着默认情况下这些常量是public static final
。
我希望代码无法编译因为这个a.DOG.sound部分。 但令我惊讶的是它没有。
它将与任何其他变量在任何类中的行为相同,如果没有默认修饰符,它只能在包内访问。