Buzz HT
Buzz HT

Reputation: 27

Modifiers used for Classes in Java

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?

Upvotes: 0

Views: 203

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369428

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.

Upvotes: 2

Benjamin Maurer
Benjamin Maurer

Reputation: 3743

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).

Upvotes: 1

Related Questions