Java final static declarations in method local classes

陌路散爱 提交于 2019-11-30 11:38:37

It's because the first two static members are assigned to compile-time constants of primitive type or type String.

From the Java Language Specification, section 8.1.3:

8.1.3. Inner Classes and Enclosing Instances

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

And from 4.12.4:

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

EDIT:

I found this surprising at first. Thinking about it more, one advantage to this limitation is that there is no need to worry about when static members of inner classes are initialized. You can move an inner class around in its containing class, without concern that the values of its static members will be changed.

More on the previous answer. The value assigned must be provable by the compiler that it is a constant. The Java compiler knows the semantics of the base types (int, float, etc.) and the java.lang.String class, but not other classes. This is can understand the constantness of the first two examples.

The compiler does not understand that Integer.valueOf(3) is also (effectively) a constant (actually not constant, but always the same) value even though a human, that knows how the Integer class works, does know that. The compiler treats this as if it was Integer.valueOf(x) which can change. It would be nice if Java offered an annotation, such as @interface Consistent, that declared the method behavior as stable for any give parameters, such as:

In Integer class: @Consistent public Integer valueOf(int x) {...}

final static Integer intThree = Integer.valueOf(3); // now compiles!

That indicates the method returns either the same or an equal object on each invocation given the same argument values. Since the argument is a constant expression, the compiler can deduce that the result will be the same/equal in all usage and can thus be treated as a constant. In this case Integer returns the same object, but it can return a different (but equal) object for much lager input values (ie. it caches values near 0).

Note that "new" always returns a different object. For new Object() it is always an object not equal to any other object.

Consider the definition of a compile-time constant expression from 15.28:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5)
  • Casts to primitive types and casts to type String (§15.16)
  • The unary operators +, -, ~, and ! (but not ++ or --) (§15.15.3, §15.15.4, §15.15.5, §15.15.6)
  • The multiplicative operators *, /, and % (§15.17)
  • The additive operators + and - (§15.18)
  • The shift operators <<, >>, and >>> (§15.19)
  • The relational operators <, <=, >, and >= (but not instanceof) (§15.20)
  • The equality operators == and != (§15.21)
  • The bitwise and logical operators &, ^, and | (§15.22)
  • The conditional-and operator && and the conditional-or operator || (§15.23, §15.24)
  • The ternary conditional operator ? : (§15.25)
  • Parenthesized expressions (§15.8.5) whose contained expression is a constant expression.
  • Simple names (§6.5.6.1) that refer to constant variables (§4.12.4).
  • Qualified names (§6.5.6.2) of the form TypeName . Identifier that refer to constant variables (§4.12.4).

Following from the definition of a compile-time constant expression, we have 4.12.4:

A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

Finally, from 8.1.3:

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!