Why static fields (not final) is restricted in inn

2019-03-08 15:43发布

Possible Duplicate:
Why does Java prohibit static fields in inner classes?

I was going through the specification and got that it is not possible to have the static member in the inner class which is not final compile time constant .

class HasStatic {
    static int j = 100;
}
class myInnerClassTest {
    class Inner extends HasStatic {
        static final int x = 3;  // OK: compile-time constant
        static int y = 4;  // Compile-time error: an inner class
    }
    static class NestedButNotInner{
        static int z = 5;    // OK: not an inner class
    }
    interface NeverInner {}   // Interfaces are never inner
}

Whereas I got from the Why can we have static final members but cant have static method in an inner class? that it can inherit the static member from its owner class. But why it shouldn't? What OOP's principal it hurts?

5条回答
家丑人穷心不美
2楼-- · 2019-03-08 15:48

As you know, inner class can inherit static member from its owner class.

class HasStatic {
    static int j = 100;
}
class myInnerClassTest {
    class Inner extends HasStatic {
    }      
    public static void main(String[] args){
        System.out.println(Inner.j);
    }
}

And it prints "100".

查看更多
甜甜的少女心
3楼-- · 2019-03-08 15:51

Because the inner class in intimately associated to the top level class you must have an instance of the outer class to create an inner via

Outer o = new Outer();
Inner i = o.new Inner();

This is therefore associated with an instance and not a class.

查看更多
爷、活的狠高调
4楼-- · 2019-03-08 16:04

According to JLS: -

8.1.3 Inner Classes and Enclosing Instances

An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).

Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final. Any local variable, used but not declared in an inner class must be definitely assigned (§16) before the body of the inner class.

Apart from these two things, which I found important.. There are many more that you can get it from there.. There is a huge explanation about inner classes, anonymous inner classes, and nested classes..

UPDATED EXPLANATION : -

Just think about it. Static block is executed during class initialization, and you cannot initialize a non-static inner class without having an instance of the enclosing class, that's the reason.

Inner classes are associated with the instance of the enclosing class.. They are like other instance attributes of the enclosing class.. Now, it doesn't make sense to embed a static field in a non-static context.. However, if you declare them as Compile Time Constants they would be allowed.

NOTE: - static final Object = null is not compile time constants.. So, you can't have them inside your inner class

On the other hand, had your inner class been static, that is actually a nested class, then you can declare your field static, as they will still be associated with the class, so you can access them even before enclosing class in instantiated..

I hope that makes sense..

UPDATE 2 : -

public class A {
   class B {
        static int x = 0;
   }
}

In the above code, static variable x will be common for every instance of class B.. Also, each instance of class A, will have it's own copy of class B (Since JVM will have to load class B every time an instance of A is created)..

So, static variable x could not have been shared between every instance of class A, unless it is a compile time constants.. (To make it more straight foreward: - You can do - B.x if you see B as outer class.. But class B is itself different for each instance of class A. So, B.x will be different for each instance of class A.. So, static variable x is not actually shared between different instances of class A.. Doesn't make sense for a static variable.)

I hope now, that makes sense..

查看更多
时光不老,我们不散
5楼-- · 2019-03-08 16:11

Your class myInnerClassTest isn't declared as static. So what would that exactly mean for it to have a static field ?

Would it be

  • the same for all instances whatever the enclosing instance ?
  • the same for all instances of this inner class having the same enclosing instance ?

At first sight most programmers would probably think it's the first case, while the encapsulation logic of the (non static) inner class should probably lead to the second choice. Either case (or both with different modifiers) would need a new definition of static which probably wasn't seen as necessary. And in either case programmers would be confused about the exact meaning.

From the specification :

An inner class is a nested class that is not explicitly or implicitly declared static.

Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5).

Inner classes may not declare static initializers (§8.7) or member interfaces, or a compile-time error occurs.

Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs.

查看更多
SAY GOODBYE
6楼-- · 2019-03-08 16:12

All the restrictions are documented in JLS #8.1.3. Inner Classes and Enclosing Instances

Because static declarations is associated with Class if you declare it inside inner class it will get associated with instance rather than class.

innerclass

Non static inner classes are members of Object. And for members initialization only happens when instance of object is created. If static variables were allowed then initialization would have happened before creation of instance.

That is why there are separate non-static and static inner classes.

You always need outer class instance to access inner class Outer.Inner only exception is static inner class for which there are no constraints which are applicable to non-static inner classes.

static class Inner {
    static final int x = 3; // OK: compile-time constant
    static int y = 4;// OK
    static class NestedButNotInner {// OK

    }

    interface NeverInner {// OK
    };
}

However constants are permitted and it is documented in JLS

查看更多
登录 后发表回答