0

According to this question, I understand that why interfaces are static. So I tried out following code:

public class ClassWithInterface {
    static interface StaticInterfaceInsideClass {   }

    interface NonStaticInterfaceInsideClass {   }

    //interface is not allowed inside non static inner classes
    //Error: The member interface InterfaceInsideInnerClass can 
    //only be defined inside a top-level class or interface or 
    //in a static context
    class InnerClassWithInterface {
        interface InterfaceInsideInnerClass {}
    }

    //Error: The member interface StaticInterfaceInsideInnerClass 
    //can only be defined inside a top-level class or interface or 
    //in a static context
    class InnerClassWithStaticInterface {
        static interface StaticInterfaceInsideInnerClass {}
    }

    static class StaticNestedClassWithInterface {
        interface InterfaceInsideStaticNestedClass {}
    }
}

//Static is not allowed for interface outside class
//Error: Illegal modifier for the interface 
//InterfaceOutsideClass; only public & abstract are permitted
static interface InterfaceOutsideClass {}

I have following doubts:

  1. If interfaces are implicitly static, why inside class for StaticInterfaceInsideClass, explicit static modifier is allowed, whereas for InterfaceOutsideClass, its not allowed?

  2. Is NonStaticInterfaceInsideClass is also static? That is, inside class, explicitly using static or not using it will not have any difference and interface will always be static by default?

  3. Why we cant have non-static interface (InterfaceInsideInnerClass) inside non static inner class (InnerClassWithInterface), but can have non-static (NonStaticInterfaceInsideClass) interface inside top level class (ClassWithInterface)? In fact, we cant even have static interface inside inner class (as for StaticInterfaceInsideInnerClass). But why?

  4. Can someone list down single or minimal rule(s) which drive all these behavior?

kaya3
  • 47,440
  • 4
  • 68
  • 97
MsA
  • 2,599
  • 3
  • 22
  • 47
  • 1
    *Member* interfaces are implicitly static. Not 'all interfaces'. [JLS 8.5.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.5.1). See my comment in your linked question. – user207421 Feb 23 '20 at 19:59
  • And 'non-static inner' is double-talk. All inner classes are non-static by definition. – user207421 Feb 23 '20 at 20:04
  • 1. Top level classes, interfaces and enums just can't be static. The grammar doesn't allow it. – Andy Turner Feb 23 '20 at 20:06
  • @AndyTurner do you mean to say "top level classes, interfaces and enums can only be static and hence it does not make sense to have explicit static modifier" as stated in [this](https://stackoverflow.com/a/7370832/6357916) answer? – MsA Feb 23 '20 at 20:12
  • 3
    @anir That answer makes no reference to the Java Language Specification. It's entirely meaningless to say that a top-level class, interface or enum is "static" because the word "static" is only used in the JLS to describe members, and not including package members. – kaya3 Feb 23 '20 at 20:41
  • 1
    @anir no, I don't. – Andy Turner Feb 23 '20 at 21:15
  • Kaya3 is right. `static` means something like "bound to the enclosing class rather than an instance of it". Top level classes have no enclosing class, so speaking of `static` does not apply. – MC Emperor Feb 23 '20 at 22:54

1 Answers1

2

Can someone list down single or minimal rule(s) which drive all these behaviour?

The same behaviour can be observed without interfaces; an inner class (i.e. a non-static nested class) cannot have its own static member class, so the following code also gives a compilation error:

class A {
    // inner class
    class B {
        // static member class not allowed here; compilation error
        static class C {}
    }
}

So the "minimal set of rules" is:

  1. "It is a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable" (JLS §8.1.3)
  2. "A member interface is implicitly static (§9.1.1). It is permitted for the declaration of a member interface to redundantly specify the static modifier." (JLS §8.5.1)

Using these two rules we can explain everything:

  • NonStaticInterfaceInsideClass is a member interface, so it is implicitly static by rule 2.
  • InterfaceInsideInnerClass is a member interface, so it is implicitly static by rule 2. It is a member of an inner class, so it is a compile-time error by rule 1.
  • StaticInterfaceInsideInnerClass is semantically the same as InterfaceInsideInnerClass; the static modifier is redundant according to rule 2.
  • InterfaceInsideStaticNestedClass is a member interface, so it is implicitly static by rule 2, but it is not forbidden by rule 1 because it is a member of a static nested class, not an inner class.
  • InterfaceOutsideClass is not allowed the static modifier, because it is not a member interface, and rule 2 only permits member interfaces to have a static modifier.
kaya3
  • 47,440
  • 4
  • 68
  • 97