默认情况下,枚举中变量的访问级别是多少

Mik*_*yev 8 java enums

最近我遇到了以下代码:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望代码因为这a.DOG.sound部分而无法编译.但令我惊讶的是,事实并非如此.我四处搜索,包括官方文档,以找出访问级别,但一无所获.是公开的还是默认的

Boa*_*ann 6

枚举中手动声明的字段的隐式访问级别是package-private,与普通类中的完全相同.因此,sound当且仅当AnimalsTestEnum在同一个包中时,您的字段才可访问.


我试图在JLS中为此找到一个可靠的引用,但遗憾的是,枚举规则遍布整个地方,被指定为普通类规则的例外,因此必须从各个部分组合规则.JLS§6.6.1确定可访问性说:

只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:

  • 如果声明了成员或构造函数public,则允许访问.

    缺少访问修饰符的接口的所有成员都是隐式的public.

  • 否则,如果声明了成员或构造函数protected,则只有在满足以下条件之一时才允许访问:

    • 从包含protected声明成员或构造函数的类的包中发生对成员或构造函数的访问.

    • 如第6.6.2节所述,访问是正确的.

  • 否则,如果使用包访问声明成员或构造函数,则仅当从声明类型的包中进行访问时才允许访问.

    声明没有访问修饰符的类成员或构造函数隐式具有包访问权限.

  • 否则,成员或构造函数被声明为private,并且当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问.

这意味着类类型(classenum)获得成员隐式具有包访问权限的规则,而接口类型(interface@interface)获得成员隐式公开的规则.

从上面可以看出,"类成员"在其"类"的定义中包含枚举,但确实如此.由于它们的广泛重叠,JLS组在许多地方枚举了类(并且注释类型同样与接口组合).JLS§8.9枚举类型说"枚举声明指定一个新的枚举类型,一种特殊的类类型"; 和JLS§8.2班级成员明确指出,"班级成员"一词是指"班级类型"的成员.

但是,枚举确实有两个关于成员可访问性的特殊规则,这些规则未包含在上面引用的部分中:

  1. 枚举常量本身(在你的榜样,他们是DOG,CATFISH)可能没有任何明确的访问修饰符(JLS第8.9.1节),并且始终public static final枚举类型(领域JLS第8.9.3节).

  2. 枚举构造函数必须是私有的(以防止人们创建额外的常量)并且是隐式私有的(JLS§8.9.2).

除了这两个例外,普通类的访问规则适用于枚举.如果您的Animals枚举已经生成public,则它及其所有常量都可以在包外部访问,但该sound字段是包私有的,除非您public明确声明,否则无法在包外部访问.


Cod*_*roc 6

如果可以导入enum,则可以访问enum常量

如果 enum可以访问(特别声明public)package它的元素也可以访问,如果没有指定修饰符,它只能在里面访问package.默认情况下,enum如果enum可访问常量,则可以访问常量public static final.

我希望代码无法编译,因为这个a.DOG.sound部分.但令我惊讶的是,事实并非如此.

它将与任何其他变量在任何类中的行为相同,如果没有默认修饰符,它只能在包内访问.