Java 创建对象时可以初始化最终变量吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18584674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a final variable be initialized when an object is created?
提问by Shivam
how it can be possible that we can initialize the final variable of the class at the creation time of the object ?
我们怎么可能在创建对象时初始化类的最终变量?
Anybody can explain it how is it possible ? ...
任何人都可以解释它怎么可能?...
采纳答案by TofuBeer
You must initialize a final variable once and only once. There are three ways to do that for an instance variable:
您必须一次且仅一次初始化最终变量。对于实例变量,有三种方法可以做到这一点:
- in the constructor
- in an instance initialization block.
- when you declare it
- 在构造函数中
- 在实例初始化块中。
- 当你声明它时
Here is an example of all three:
这是所有三个的示例:
public class X
{
private final int a;
private final int b;
private final int c = 10;
{
b = 20;
}
public X(final int val)
{
a = val;
}
}
In each case the code is run once when you call new X(...)
and there is no way to call any of those again, which satisfies the requirement of the initialization happening once and only once per instance.
在每种情况下,当您调用时,代码都运行一次,new X(...)
并且无法再次调用其中任何一个,这满足了每个实例仅发生一次初始化的要求。
回答by AurA
Final variables which is not initialized during declaration are called blank final variable and must be initialized on all constructor either explicitly or by calling this()
. Failure to do so compiler will complain as "final variable (name) might not be initialized".
在声明期间未初始化的最终变量称为空白最终变量,必须进行初始化on all constructor either explicitly or by calling this()
。不这样做编译器会抱怨"final variable (name) might not be initialized".
As per Wikipedia
根据维基百科
A final variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called a "blank final"
variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
final 变量只能通过初始化程序或赋值语句初始化一次。它不需要在声明点初始化:这称为"blank final"
变量。必须在声明它的类的每个构造函数的末尾明确分配一个类的空白最终实例变量;类似地,必须在声明它的类的静态初始化程序中明确分配一个空白的最终静态变量;否则,在这两种情况下都会发生编译时错误。
Eg.
例如。
public class Sphere {
// pi is a universal constant, about as constant as anything can be.
public static final double PI = 3.141592653589793;
public final double radius;
public final double xPos;
public final double yPos;
public final double zPos;
Sphere(double x, double y, double z, double r) {
radius = r;
xPos = x;
yPos = y;
zPos = z;
}
[...]
}
For more details read the wiki page http://en.wikipedia.org/wiki/Final_(Java)
有关更多详细信息,请阅读 wiki 页面 http://en.wikipedia.org/wiki/Final_(Java)
回答by rocketboy
Why not. Like this
为什么不。像这样
public class GenericFoo{
final int var;
GenericFoo(){
var = 100;
}
}
回答by Prabhaker A
You can initialize final instance variables before constructor completes.
According to JSL
您可以在构造函数完成之前初始化最终实例变量。
根据JSL
A blank final instance variable must be definitely assigned at the end of every constructor of the class in which it is declared; otherwise a compile-time error occurs.
必须在声明它的类的每个构造函数的末尾明确分配一个空白的最终实例变量;否则会发生编译时错误。
Blank final variable in Java is a final variable which is not initialized while declaration
Java中的空白最终变量是声明时未初始化的最终变量
So there are 2 ways to do it.
所以有2种方法可以做到。
way 1:In constructor
方式1:在构造函数中
class Program {
final int i3;
Program() {
i3 = 10;
}
}
way 2: In instance block
方式2:在实例块中
class Program {
final int i3;
{
i3 = 10;
}
}
回答by Peter Lawrey
A final
value is one which can only be set once, and only in the constructor. There is no reason it cannot be set by the constructor to any value you like.
一个final
值只能设置一次,并且只能在构造函数中设置。没有理由不能由构造函数将其设置为您喜欢的任何值。
If you had a value which you wanted to be a constant for all instance, you would make it static final
and you would NOT be able to set it in a constructor. Perhaps you are confusing the two.
如果你有一个值,你想成为所有实例的常量,你会创建它static final
并且你不能在构造函数中设置它。也许你把两者混淆了。
回答by Arne Burmeister
If you mean a static final member you can use a static initializer:
如果您的意思是静态最终成员,则可以使用静态初始值设定项:
class Example {
public final static Map<String,Object> C;
static {
C = new HashMap<>();
C.put("hi", 5);
}
}
回答by bubooal
This is possible due to the way in which the JVM works internally and the way Java was designed.
由于 JVM 的内部工作方式和 Java 的设计方式,这是可能的。
After your code is compiled, the .class file generated will contain the bytecode representation of your code. A Class file is nothing but a bunch of bytes structured in a defined order which can be interpreted by the JVM.
编译代码后,生成的 .class 文件将包含代码的字节码表示。类文件只不过是一组按定义顺序构造的字节,JVM 可以解释这些字节。
In a Class File structure you will be able to find something called the Constant Pool, which is nothing but a symbolic reference table used by the JVM when classes are loaded. Your final variables will be found here whether they are initialized or not as a literal.
在类文件结构中,您将能够找到称为常量池的东西,它只不过是加载类时 JVM 使用的符号引用表。无论是否初始化为文字,您的最终变量都将在此处找到。
So now that you know this, let's move on and think of what the final modifier means, it means nothing but a way of telling the JVM that in this case a variable will be assigned a value and once this is done, a re-assignment operation on that variable will not be permitted, so as the Java Language documentation states, a final variable can be assigned a value once and only once.
所以现在你知道了这一点,让我们继续思考 final 修饰符的含义,它只是告诉 JVM 在这种情况下,一个变量将被赋值,一旦完成,重新赋值不允许对该变量进行操作,因此正如 Java 语言文档所述,最终变量只能被赋值一次且仅一次。
Now that you have this background, in order to answer your question directly:
现在你有了这个背景,为了直接回答你的问题:
Whether your variable is an object or a primitive type, the value to a final variable which is not a class member (meaning is not static) will be automatically set by the JVM using the value in the runtime constant pool for your object OR if this variable is not initialized on declaration, then it will be required to be set when the constructor runs. All of this is possible because Java was designed this way to provide programmers some flexibility on variable assignment to avoid hard-coding and to provide a way to assign objects to final references.
无论您的变量是对象还是原始类型,JVM 都会使用对象的运行时常量池中的值自动设置不是类成员(意思是不是静态的)的最终变量的值,或者如果这样变量未在声明时初始化,则需要在构造函数运行时对其进行设置。所有这一切都是可能的,因为 Java 的这种设计方式为程序员提供了一些变量分配的灵活性,以避免硬编码,并提供了一种将对象分配给最终引用的方法。
Just as a final tip, stop thinking as final variables as constants in C++. They might seem similar but they are not, they are handled in completely different ways.
作为最后的提示,停止将最终变量视为 C++ 中的常量。它们可能看起来很相似,但实际上并非如此,它们的处理方式完全不同。
回答by Anish
As you know instance variable is associated with class object only ,And final keyword before variable means you can't change the value of variable so variable existence is only when object is created that's why we can assign the final variable value three ways as mentioned above before creation of object(eg. by static block,when you declare) or at the time of creation of object(eg. through constructor)
如您所知,实例变量仅与类对象相关联,变量前的 final 关键字意味着您无法更改变量的值,因此变量仅在创建对象时才存在,这就是为什么我们可以通过上述三种方式分配最终变量值在创建对象之前(例如通过静态块,当您声明时)或在创建对象时(例如通过构造函数)