最终的、不可变的对象不是常量?
Final, immutable objects are not constants?
class Integer
是 int
原始类型 (https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html). An object is considered immutable if its state cannot change after it is constructed (https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) 的包装器。
我在这里的理解是,您只能通过引用完全不同的 Integer
对象来更改 Integer
变量的值。
通过声明一个变量final,我们可以保证:
Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.
再一次,根据 immutable 文档:
An object is considered immutable if its state cannot change after it is constructed.
因此,最终的、不可变的 Integer
不允许以任何方式更改其值。
如果这是正确的,为什么我们不允许声明一个 public static final Integer
变量?
following code 以不同的方式声明了一个 public static final Integer
,并且所有这些 return 都是编译时错误:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public class Constants {
public static final String STRING_CONSTANT = "string_constant";
public static final int INTEGER_CONSTANT = 1; // allowed
//public static final Integer INTEGER_CONSTANT = 1; // not allowed
//public static final Integer INTEGER_CONSTANT = new Integer("1"); // not allowed
//public static final Integer INTEGER_CONSTANT = Integer.valueOf(1); // not allowed
}
public static void main (String[] args) throws java.lang.Exception
{
System.out.println("STRING_CONSTANT = " + Constants.STRING_CONSTANT);
System.out.println("INTEGER_CONSTANT = " + Constants.INTEGER_CONSTANT);
}
}
抛出的异常是:
Main.java:12: error: Illegal static declaration in inner class Ideone.Constants
public static final Integer INTEGER_CONSTANT = 1;
^
modifier 'static' is only allowed in constant variable declarations
1 error
有人能解释一下为什么我们不允许声明 public static final Integer
吗?
编辑:我想知道为什么 public static final Integer
是不允许的,而 public static final String
和 public static final int
是允许的,而不是寻找可以编译的代码。
问题不在于常量的声明,而在于它是在非静态的内部 class 中声明的。将 class 的声明更改为 static 就可以了:
public static class Constants {
public static final String STRING_CONSTANT = "string_constant";
public static final int INTEGER_CONSTANT = 1; // allowed
public static final Integer INTEGER_CONSTANT1 = 1;
public static final Integer INTEGER_CONSTANT2 = new Integer("1");
public static final Integer INTEGER_CONSTANT3 = Integer.valueOf(1);
}
看你的定义。这不是静态最终整数的问题。但是内部(嵌套)class。内部 class 默认是父 class 的 属性 并且做需要做的事情。如果你想让这个功能对其他人可见 classes make inner class static 并且你的代码将工作。但是如果你想使用一些全局配置 class 单独声明它而不是 subclass。
Java 允许 public static final Integer
,但不是静态内部 classes。将声明移至 class Ideone 或将 class 常量设为静态。
仅当初始化被视为仅适用于字符串和原始类型的编译器常量时,才可以在内部 classes 中声明 public static final
字段。
public static final String a = new String("ds"); //will not work
您可以在 JLS 中找到这背后的原因。
8.1.3. Inner Classes and Enclosing Instances
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 (§4.12.4).
然后,我们可以查看常量变量的定义:
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression
这就是为什么您可以声明原始类型或 String
常量的原因。但是 Integer
class 和其他拳击 class 不是该例外的一部分,它们与任何其他 class.
一样都是实例
来源:
内联常量
如果我们添加以下内容:
A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.
我们可以看到那些常量在 运行 时并不存在,引用在编译时解析。
代码:
final static int INTEGER_CONSTANT = 1;
int value = INTEGER_CONSTANT;
运行 时间 "code" :
int value = 1;
根据 JLS,编译时常量表达式是表示原始类型值或字符串的表达式。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
class Integer
是 int
原始类型 (https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html). An object is considered immutable if its state cannot change after it is constructed (https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html) 的包装器。
我在这里的理解是,您只能通过引用完全不同的 Integer
对象来更改 Integer
变量的值。
通过声明一个变量final,我们可以保证:
Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.
再一次,根据 immutable 文档:
An object is considered immutable if its state cannot change after it is constructed.
因此,最终的、不可变的 Integer
不允许以任何方式更改其值。
如果这是正确的,为什么我们不允许声明一个 public static final Integer
变量?
following code 以不同的方式声明了一个 public static final Integer
,并且所有这些 return 都是编译时错误:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public class Constants {
public static final String STRING_CONSTANT = "string_constant";
public static final int INTEGER_CONSTANT = 1; // allowed
//public static final Integer INTEGER_CONSTANT = 1; // not allowed
//public static final Integer INTEGER_CONSTANT = new Integer("1"); // not allowed
//public static final Integer INTEGER_CONSTANT = Integer.valueOf(1); // not allowed
}
public static void main (String[] args) throws java.lang.Exception
{
System.out.println("STRING_CONSTANT = " + Constants.STRING_CONSTANT);
System.out.println("INTEGER_CONSTANT = " + Constants.INTEGER_CONSTANT);
}
}
抛出的异常是:
Main.java:12: error: Illegal static declaration in inner class Ideone.Constants
public static final Integer INTEGER_CONSTANT = 1;
^
modifier 'static' is only allowed in constant variable declarations
1 error
有人能解释一下为什么我们不允许声明 public static final Integer
吗?
编辑:我想知道为什么 public static final Integer
是不允许的,而 public static final String
和 public static final int
是允许的,而不是寻找可以编译的代码。
问题不在于常量的声明,而在于它是在非静态的内部 class 中声明的。将 class 的声明更改为 static 就可以了:
public static class Constants {
public static final String STRING_CONSTANT = "string_constant";
public static final int INTEGER_CONSTANT = 1; // allowed
public static final Integer INTEGER_CONSTANT1 = 1;
public static final Integer INTEGER_CONSTANT2 = new Integer("1");
public static final Integer INTEGER_CONSTANT3 = Integer.valueOf(1);
}
看你的定义。这不是静态最终整数的问题。但是内部(嵌套)class。内部 class 默认是父 class 的 属性 并且做需要做的事情。如果你想让这个功能对其他人可见 classes make inner class static 并且你的代码将工作。但是如果你想使用一些全局配置 class 单独声明它而不是 subclass。
Java 允许 public static final Integer
,但不是静态内部 classes。将声明移至 class Ideone 或将 class 常量设为静态。
仅当初始化被视为仅适用于字符串和原始类型的编译器常量时,才可以在内部 classes 中声明 public static final
字段。
public static final String a = new String("ds"); //will not work
您可以在 JLS 中找到这背后的原因。
8.1.3. Inner Classes and Enclosing Instances
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 (§4.12.4).
然后,我们可以查看常量变量的定义:
A constant variable is a final variable of primitive type or type String that is initialized with a constant expression
这就是为什么您可以声明原始类型或 String
常量的原因。但是 Integer
class 和其他拳击 class 不是该例外的一部分,它们与任何其他 class.
来源:
内联常量
如果我们添加以下内容:
A reference to a field that is a constant variable (§4.12.4) must be resolved at compile time to the value V denoted by the constant variable's initializer.
我们可以看到那些常量在 运行 时并不存在,引用在编译时解析。
代码:
final static int INTEGER_CONSTANT = 1;
int value = INTEGER_CONSTANT;
运行 时间 "code" :
int value = 1;
根据 JLS,编译时常量表达式是表示原始类型值或字符串的表达式。 https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28