1

my code is like this:

    public class BookStore {
             class Enumerator1 {   
                 static int b = 0;//requires final
             }

         public String searchBook(final String criteria) {
             class Enumerator2 {   
                 static int b = 0;//requires final
             }
             return "";
         }
    }

here i can't declare b as static it requires to be constant.I couldn't understand why?

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
Sarkhan
  • 1,281
  • 1
  • 11
  • 33
  • 1
    Here's [the relevant JLS section](https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.3) - "Inner classes may not declare static members, unless they are constant variables" – resueman Jul 01 '16 at 13:21
  • See also http://stackoverflow.com/questions/18526099/error-field-name-cannot-be-declared-static – Raedwald Jul 01 '16 at 13:56
  • Note that this restriction is removed in Java 16+. – Stephen C Feb 12 '23 at 22:57

3 Answers3

3

Because the class itself actually isn't static so non-final static declaration would mean having one instance per parent instance which is not possible. "final" is basically a constant so it doesn't cause any problems.

If you declare the inner class static as well, you can have static variables inside:

public class BookStore {
         static class Enumerator1 {   
             static int b = 0;// works
         }

     public String searchBook(final String criteria) {
         class Enumerator2 {   
             final static int b = 0; // still necessary as the class can't be static here
         }
         return "";
     }
}
Zbynek Vyskovsky - kvr000
  • 18,186
  • 3
  • 35
  • 43
1

All static declarations for inner classes must be in the parent class. A static final is treated as a constant and therefore actually takes no real static space so you can use them in inner calsses.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
1

JLS states that "Inner classes may not declare static members, unless they are constant variables". The reason behind this prohibition is that a class variable in an object-dependent class has high potential for creating confusion.

Consider a simple example:

class Parent {
    public class Child {
        static int count = 1; // Let's pretend that it is possible
        public void increment() {
            count++;
        }
        public void show() {
            System.out.println(count);
        }
    }
    public Child generateChild() {
        return new Child();
    }
}

Now let's say we do this:

Parent p1 = new Parent();
Parent.Child c1 = p1.generateChild();
Parent p2 = new Parent();
Parent.Child c2 = p2.generateChild();
c2.show();
c1.increment();
c2.show();

An increment on a child of parent 1 causes a change in a child of a different parent, even though a Child class is attached to its Parent class, so children of different parents should have independent contexts.

Java language designers reasoned that if you indeed want this behavior, you would have no problem putting the static variable in the parent class.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523