sachin
sachin

Reputation: 1396

Inner-Class and String Literals in Java

Following two cases seem to work:

public class A {
    private class B {
        public static final String str = "str";
    }
}

public class A {
    private static class B {
        public static final String str = new String("str");
    }
}

But Following gives an error as specified in comment:

public class A {    
    private class B {
    //The field str cannot be declared static; 
    //static fields can only be declared in static or top level types
        public static final String str = new String("str"); 
    }
}

Why it is allowed in first two cases and why it is causing issue in last one?

Upvotes: 2

Views: 250

Answers (3)

Stephen C
Stephen C

Reputation: 719739

The JLS clearly states this restriction; see Yishai's answer.

One possible explanation for "why" is that there would be an expectation that a non-constant static initializer expression could refer to statics or non-statics in the enclosing class. The first would potentially lead to conceptual or implementation difficulties in the ordering of class (static) initialization. The second would be unimplementable, and would result in a compilation error that could be hard to comprehend. (Consider how often novices trip up on the static / non-static access restrictions in simple methods.)

I think they simply took the easy route and banned this. (KISS works for me ...) They possibly thought they could relax the restriction in a later revision, but have then not seen the need to do this.

Upvotes: 0

Hot Licks
Hot Licks

Reputation: 47759

I'm guessing the restriction is due to how new String("str") is implemented. Initialization of a member with a literal string can be accomplished with entries in the constant pool, but new String("str") requires actual code execution, so this must be accomplished with actual bytecodes in the static init method.

The screwy inner class scheme give me headaches just thinking about it (it's really a kludge internally), so I can't explain exactly what the problem is, but I suspect that the static init method runs at an inappropriate time in situation described above, so either the results aren't reliable or the system would be unable to handle exceptions resulting from errors in the static init method.

Upvotes: 1

Yishai
Yishai

Reputation: 91931

This is required by the JLS, section 8.1.3. I never saw a reason for it, but I suspect that an inner class that is not static requires an instance of the outer class, but declarations as static break that concept, and by allowing them it would create a whole other set of rules to handle just that case, which was deemed not worth it. Whereas when it is static, it is really just like any other class, that just happens to be in the same source file.

Upvotes: 4

Related Questions