Java 最后,不可变对象不是常量?
类Java 最后,不可变对象不是常量?,java,static,immutability,final,Java,Static,Immutability,Final,类Integer是int原语类型()的包装器。如果对象在构造()后状态无法更改,则认为该对象是不可变的 我在这里理解的是,您只能通过引用完全不同的Integer对象来更改Integer变量的值 通过声明变量,我们可以确保: 一旦分配了最终变量,它总是包含相同的值。如果最后一个变量包含对对象的引用,则对象的状态可能会因对该对象的操作而改变,但该变量将始终引用同一对象 同样,根据文件: 如果对象的状态在构造后无法更改,则认为该对象是不可变的 因此,最终的、不可变的整数将不允许以任何方式更改其值 如果
Integer
是int
原语类型()的包装器。如果对象在构造()后状态无法更改,则认为该对象是不可变的
我在这里理解的是,您只能通过引用完全不同的Integer
对象来更改Integer
变量的值
通过声明变量,我们可以确保:
一旦分配了最终变量,它总是包含相同的值。如果最后一个变量包含对对象的引用,则对象的状态可能会因对该对象的操作而改变,但该变量将始终引用同一对象
同样,根据文件:
如果对象的状态在构造后无法更改,则认为该对象是不可变的
因此,最终的、不可变的整数
将不允许以任何方式更改其值
如果这是正确的,为什么不允许我们声明一个公共静态最终整数
变量
以不同的方式声明了一个公共静态最终整数
,并且它们都返回编译时错误:
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 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);
}
看看你的定义。这不是静态最终整数的问题。但是内部(嵌套)类。内部类是父类的默认属性,执行需要执行的操作。如果您想让这个功能对其他类可见,请将内部类设置为静态,这样您的代码就可以工作了。但是,如果您想使用一些全局配置类,请单独声明它,而不是作为子类 Java允许
公共静态最终整数
,但不允许在非静态内部类中。将声明移动到类Ideone或使类常量为静态。
只有当初始化被认为是编译器常量时,才可以在内部类中声明公共静态final
字段,编译器常量仅适用于字符串和primative类型
公共静态最终字符串a=新字符串(“ds”)//将不起作用
您可以在JLS中找到原因
如果内部类声明的成员是显式或隐式静态的,则为编译时错误,除非该成员是常量变量(§4.12.4)
然后,我们可以检查常量变量的定义:
常量变量是使用常量表达式初始化的基元类型或字符串类型的最终变量
这就是为什么允许您声明原语或字符串
常量。但是Integer
类和其他装箱类不是该异常的一部分,它们与任何其他类一样都是实例
资料来源:
内联常数
如果我们加上以下内容:
对常量变量(§4.12.4)字段的引用必须在编译时解析为常量变量初始值设定项表示的值V
我们可以看到,这些常量在运行时并不存在,引用在编译时解析
代码:
final static int INTEGER_CONSTANT = 1;
int value = INTEGER_CONSTANT;
运行时“代码”:
根据JLS,编译时常量表达式是表示基元类型的值或字符串的表达式 您的问题并没有指出您想要在内部类中声明静态实例的事实。您可以在该内部类中声明基元常量这一事实确实引起了我的兴趣!您的类
常量
是一个非静态的内部类。它不能有静态成员。谢谢你的评论。在这种情况下,为什么我们可以声明一个public static final String
和public static final int
?我猜编译器正在内联编译时常量,因此您可以避免一些通常不允许的事情。整数可以是运行时常量,但不是编译时常量,因此它不适用于此。这在这里有一定的优先级,谢谢您的回答。但是,我并不是在寻找代码的解决方案,而是为了解释为什么不允许使用Integer和String/int。
int value = 1;