Java中用于类的修饰符有:

huangapple go评论64阅读模式
英文:

Modifiers used for Classes in Java

问题

我知道Java中的类只使用"public"和"default(没有修饰符)",当您尝试将类声明为"private"或"protected"时,它会产生编译错误,这对我来说是有道理的。

但是,为什么这个页面说"类可以有上述4个修饰符中的任何修饰符"呢?

有人可以解释一下吗?

英文:

I am aware that classes in Java only use "public" and "default (no modifier)" and when you try to declare a class as "private" or "protected", it gives out a compilation error and it makes sense to me.

But then, why does this page says "classes can have any modifiers out of the 4 mentioned above".

Can someone please explain this to me?

答案1

得分: 2

有更多合法的组合。只是为了好玩,我写了一个小脚本来生成所有可能的组合,然后我删除了导致编译错误的组合,这些是我剩下的合法组合:

class Test {
    // ... 代码 ...
}

因此,如果包括 Java 14 的实验性 record,总共有 112 种合法的组合;或者分开计算,record 有 32 种合法的修饰符组合,interface 也有 32 种,仅考虑类的话则有 48 种。

最明显的非法组合有:

  • abstractfinalabstract 表示“包含未实现的成员,必须由子类实现”,而 final 表示“不能被子类化”,因此,一个需要子类化但又不能有子类的类是没有意义的。
  • 基于同样的原因,不能有被声明为 finalinterface:一个 interface 在本质上是完全抽象的,因为它应该由实现它的 class 来实现。
  • 相反地,record 是隐式地 final,因此不能是 abstract 的。
英文:

There are a lot more legal combinations. Just for fun, I wrote a little script which generates all possible combinations, then I deleted the ones that caused compilation errors, and these are the legal ones I was left with:

class Test {
                                             class     Default__ConcreteInstanceVirtualLoosefp_Class     {}
                                             interface Default__ConcreteInstanceVirtualLoosefp_Interface {}
                                             record    Default__ConcreteInstanceVirtualLoosefp_Record()  {}
                                    strictfp class     Default__ConcreteInstanceVirtualStrictfpClass     {}
                                    strictfp interface Default__ConcreteInstanceVirtualStrictfpInterface {}
                                    strictfp record    Default__ConcreteInstanceVirtualStrictfpRecord()  {}
                              final          class     Default__ConcreteInstanceFinal__Loosefp_Class     {}
                              final          record    Default__ConcreteInstanceFinal__Loosefp_Record()  {}
                              final strictfp class     Default__ConcreteInstanceFinal__StrictfpClass     {}
                              final strictfp record    Default__ConcreteInstanceFinal__StrictfpRecord()  {}
                       static                class     Default__ConcreteStatic__VirtualLoosefp_Class     {}
                       static                interface Default__ConcreteStatic__VirtualLoosefp_Interface {}
                       static                record    Default__ConcreteStatic__VirtualLoosefp_Record()  {}
                       static       strictfp class     Default__ConcreteStatic__VirtualStrictfpClass     {}
                       static       strictfp interface Default__ConcreteStatic__VirtualStrictfpInterface {}
                       static       strictfp record    Default__ConcreteStatic__VirtualStrictfpRecord()  {}
                       static final          class     Default__ConcreteStatic__Final__Loosefp_Class     {}
                       static final          record    Default__ConcreteStatic__Final__Loosefp_Record()  {}
                       static final strictfp class     Default__ConcreteStatic__Final__StrictfpClass     {}
                       static final strictfp record    Default__ConcreteStatic__Final__StrictfpRecord()  {}
              abstract                       class     Default__AbstractInstanceVirtualLoosefp_Class     {}
              abstract                       interface Default__AbstractInstanceVirtualLoosefp_Interface {}
              abstract              strictfp class     Default__AbstractInstanceVirtualStrictfpClass     {}
              abstract              strictfp interface Default__AbstractInstanceVirtualStrictfpInterface {}
              abstract static                class     Default__AbstractStatic__VirtualLoosefp_Class     {}
              abstract static                interface Default__AbstractStatic__VirtualLoosefp_Interface {}
              abstract static       strictfp class     Default__AbstractStatic__VirtualStrictfpClass     {}
              abstract static       strictfp interface Default__AbstractStatic__VirtualStrictfpInterface {}
    public                                   class     Public___ConcreteInstanceVirtualLoosefp_Class     {}
    public                                   interface Public___ConcreteInstanceVirtualLoosefp_Interface {}
    public                                   record    Public___ConcreteInstanceVirtualLoosefp_Record()  {}
    public                          strictfp class     Public___ConcreteInstanceVirtualStrictfpClass     {}
    public                          strictfp interface Public___ConcreteInstanceVirtualStrictfpInterface {}
    public                          strictfp record    Public___ConcreteInstanceVirtualStrictfpRecord()  {}
    public                    final          class     Public___ConcreteInstanceFinal__Loosefp_Class     {}
    public                    final          record    Public___ConcreteInstanceFinal__Loosefp_Record()  {}
    public                    final strictfp class     Public___ConcreteInstanceFinal__StrictfpClass     {}
    public                    final strictfp record    Public___ConcreteInstanceFinal__StrictfpRecord()  {}
    public             static                class     Public___ConcreteStatic__VirtualLoosefp_Class     {}
    public             static                interface Public___ConcreteStatic__VirtualLoosefp_Interface {}
    public             static                record    Public___ConcreteStatic__VirtualLoosefp_Record()  {}
    public             static       strictfp class     Public___ConcreteStatic__VirtualStrictfpClass     {}
    public             static       strictfp interface Public___ConcreteStatic__VirtualStrictfpInterface {}
    public             static       strictfp record    Public___ConcreteStatic__VirtualStrictfpRecord()  {}
    public             static final          class     Public___ConcreteStatic__Final__Loosefp_Class     {}
    public             static final          record    Public___ConcreteStatic__Final__Loosefp_Record()  {}
    public             static final strictfp class     Public___ConcreteStatic__Final__StrictfpClass     {}
    public             static final strictfp record    Public___ConcreteStatic__Final__StrictfpRecord()  {}
    public    abstract                       class     Public___AbstractInstanceVirtualLoosefp_Class     {}
    public    abstract                       interface Public___AbstractInstanceVirtualLoosefp_Interface {}
    public    abstract              strictfp class     Public___AbstractInstanceVirtualStrictfpClass     {}
    public    abstract              strictfp interface Public___AbstractInstanceVirtualStrictfpInterface {}
    public    abstract static                class     Public___AbstractStatic__VirtualLoosefp_Class     {}
    public    abstract static                interface Public___AbstractStatic__VirtualLoosefp_Interface {}
    public    abstract static       strictfp class     Public___AbstractStatic__VirtualStrictfpClass     {}
    public    abstract static       strictfp interface Public___AbstractStatic__VirtualStrictfpInterface {}
    private                                  class     Private__ConcreteInstanceVirtualLoosefp_Class     {}
    private                                  interface Private__ConcreteInstanceVirtualLoosefp_Interface {}
    private                                  record    Private__ConcreteInstanceVirtualLoosefp_Record()  {}
    private                         strictfp class     Private__ConcreteInstanceVirtualStrictfpClass     {}
    private                         strictfp interface Private__ConcreteInstanceVirtualStrictfpInterface {}
    private                         strictfp record    Private__ConcreteInstanceVirtualStrictfpRecord()  {}
    private                   final          class     Private__ConcreteInstanceFinal__Loosefp_Class     {}
    private                   final          record    Private__ConcreteInstanceFinal__Loosefp_Record()  {}
    private                   final strictfp class     Private__ConcreteInstanceFinal__StrictfpClass     {}
    private                   final strictfp record    Private__ConcreteInstanceFinal__StrictfpRecord()  {}
    private            static                class     Private__ConcreteStatic__VirtualLoosefp_Class     {}
    private            static                interface Private__ConcreteStatic__VirtualLoosefp_Interface {}
    private            static                record    Private__ConcreteStatic__VirtualLoosefp_Record()  {}
    private            static       strictfp class     Private__ConcreteStatic__VirtualStrictfpClass     {}
    private            static       strictfp interface Private__ConcreteStatic__VirtualStrictfpInterface {}
    private            static       strictfp record    Private__ConcreteStatic__VirtualStrictfpRecord()  {}
    private            static final          class     Private__ConcreteStatic__Final__Loosefp_Class     {}
    private            static final          record    Private__ConcreteStatic__Final__Loosefp_Record()  {}
    private            static final strictfp class     Private__ConcreteStatic__Final__StrictfpClass     {}
    private            static final strictfp record    Private__ConcreteStatic__Final__StrictfpRecord()  {}
    private   abstract                       class     Private__AbstractInstanceVirtualLoosefp_Class     {}
    private   abstract                       interface Private__AbstractInstanceVirtualLoosefp_Interface {}
    private   abstract              strictfp class     Private__AbstractInstanceVirtualStrictfpClass     {}
    private   abstract              strictfp interface Private__AbstractInstanceVirtualStrictfpInterface {}
    private   abstract static                class     Private__AbstractStatic__VirtualLoosefp_Class     {}
    private   abstract static                interface Private__AbstractStatic__VirtualLoosefp_Interface {}
    private   abstract static       strictfp class     Private__AbstractStatic__VirtualStrictfpClass     {}
    private   abstract static       strictfp interface Private__AbstractStatic__VirtualStrictfpInterface {}
    protected                                class     ProtectedConcreteInstanceVirtualLoosefp_Class     {}
    protected                                interface ProtectedConcreteInstanceVirtualLoosefp_Interface {}
    protected                                record    ProtectedConcreteInstanceVirtualLoosefp_Record()  {}
    protected                       strictfp class     ProtectedConcreteInstanceVirtualStrictfpClass     {}
    protected                       strictfp interface ProtectedConcreteInstanceVirtualStrictfpInterface {}
    protected                       strictfp record    ProtectedConcreteInstanceVirtualStrictfpRecord()  {}
    protected                 final          class     ProtectedConcreteInstanceFinal__Loosefp_Class     {}
    protected                 final          record    ProtectedConcreteInstanceFinal__Loosefp_Record()  {}
    protected                 final strictfp class     ProtectedConcreteInstanceFinal__StrictfpClass     {}
    protected                 final strictfp record    ProtectedConcreteInstanceFinal__StrictfpRecord()  {}
    protected          static                class     ProtectedConcreteStatic__VirtualLoosefp_Class     {}
    protected          static                interface ProtectedConcreteStatic__VirtualLoosefp_Interface {}
    protected          static                record    ProtectedConcreteStatic__VirtualLoosefp_Record()  {}
    protected          static       strictfp class     ProtectedConcreteStatic__VirtualStrictfpClass     {}
    protected          static       strictfp interface ProtectedConcreteStatic__VirtualStrictfpInterface {}
    protected          static       strictfp record    ProtectedConcreteStatic__VirtualStrictfpRecord()  {}
    protected          static final          class     ProtectedConcreteStatic__Final__Loosefp_Class     {}
    protected          static final          record    ProtectedConcreteStatic__Final__Loosefp_Record()  {}
    protected          static final strictfp class     ProtectedConcreteStatic__Final__StrictfpClass     {}
    protected          static final strictfp record    ProtectedConcreteStatic__Final__StrictfpRecord()  {}
    protected abstract                       class     ProtectedAbstractInstanceVirtualLoosefp_Class     {}
    protected abstract                       interface ProtectedAbstractInstanceVirtualLoosefp_Interface {}
    protected abstract              strictfp class     ProtectedAbstractInstanceVirtualStrictfpClass     {}
    protected abstract              strictfp interface ProtectedAbstractInstanceVirtualStrictfpInterface {}
    protected abstract static                class     ProtectedAbstractStatic__VirtualLoosefp_Class     {}
    protected abstract static                interface ProtectedAbstractStatic__VirtualLoosefp_Interface {}
    protected abstract static       strictfp class     ProtectedAbstractStatic__VirtualStrictfpClass     {}
    protected abstract static       strictfp interface ProtectedAbstractStatic__VirtualStrictfpInterface {}
}

So, there are a total of 112 legal combinations if you include Java 14 experimental records, or counted separately, 32 legal combinations of modifiers for records, 32 as well for interfaces, and 48 if you only count classes.

The most obvious illegal combinations are:

  • abstract and final: abstract means "contains un-implemented members that must be implemented by subclasses" and final means "cannot be subclassed", so clearly, a class that requires subclassing but cannot have subclasses doesn't make sense.
  • For the same reason, you can't have interfaces that are final: an interface is implicitly fully abstract, since it is supposed to be implemented by its implementing classes.
  • And conversely, records are implicitly final, so they cannot be abstract.

答案2

得分: 1

就像文本所说:

并非所有的修饰符都可以用在所有的类上。

但是,例如,内部类 可以是私有的/受保护的。

public class Foo {
    private Bar bar = new Bar(42);

    private static class Bar {
        private int answer;

        Bar(int theAnswer) {
            this.answer = theAnswer;
        }
    }
}

这在某些持有数据的 POJO 或者某些内部实现细节上是有意义的,您可能希望对其进行封装,但不泄露出来(甚至可以在受保护的情况下进行重写)。

英文:

Like the text says:

> Not all modifiers are allowed on all classes

But, e.g., inner classes can be private/protected.

public class Foo {
private Bar bar = new Bar(42);
private static class Bar {
private int answer;
Bar(int theAnswer) {
this.answer = theAnswer;
}
}
}

This can make sense for some POJO holding data, or some internal implementation detail that you want to encapsulate, but not leak out (and you can even override if it's protected).

huangapple
  • 本文由 发表于 2020年8月15日 19:19:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63425447.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定