public class A
{
private static final int x;
public A()
{
x = 5;
}
}
final
表示变量只能分配一次(在构造函数中)。static
表示它是一个类实例。我不明白为什么这是禁止的。这些关键词在哪里相互干扰?
答案 0 :(得分:171)
每次创建类的实例时都会调用构造函数。因此,上面的代码意味着每次创建实例时都会重新初始化x的值。但是因为变量被声明为final(和static),所以你只能这样做
class A {
private static final int x;
static {
x = 5;
}
}
但是,如果你删除静态,你可以这样做:
class A {
private final int x;
public A() {
x = 5;
}
}
或者这个:
class A {
private final int x;
{
x = 5;
}
}
答案 1 :(得分:16)
在加载类时初始化静态最终变量。构造函数可以稍后调用,或者根本不调用。此外,构造函数将被多次调用(每个新对象),因此该字段不再是最终的。
如果您需要自定义逻辑来初始化静态最终字段,请将其放在静态块中
答案 2 :(得分:6)
考虑第二次实例化对象时会发生什么。它试图将它设置为AGAIN,这是一个静态的决赛明确禁止的。它只能为整个类设置一次,而不是实例。
您应该在声明时设置值
private static final x=5;
如果您需要额外的逻辑或更复杂的实例化,可以在静态初始化程序块中完成。
答案 3 :(得分:5)
static
表示该变量在应用程序上是唯一的。
final
表示只应设置一次。
如果在构造函数中设置它,则允许多次设置变量。
因此,您应该直接初始化它或提出一个静态方法来初始化它。
答案 4 :(得分:3)
最终并不意味着必须在构造函数中初始化。 通常这就是做的事情:
private static final int x = 5;
static 代替表示该变量将通过该类的多个实例共享。例如:
public class Car {
static String name;
public Car(String name) {
this.name = name;
}
}
...
Car a = new Car("Volkswagen");
System.out.println(a.name); // Produces Volkswagen
Car b = new Car("Mercedes");
System.out.println(b.name); // Produces Mercedes
System.out.println(a.name); // Produces Mercedes
答案 5 :(得分:2)
想一想。您可以使用您的代码执行此操作:
A a = new A();
A b = new A(); // Wrong... x is already initialised
初始化x的正确方法是:
public class A
{
private static final int x = 5;
}
或
public class A
{
private static final int x;
static
{
x = 5;
}
}
答案 6 :(得分:0)
methods: {
getLog() {
this.users.forEach(element => {
element.logs.forEach((log) => {
this.Logs.push(log);
})
});
var unfinished = this.Logs.filter((log) => {
return log.finished == false;
});
console.log(unfinished);
const input = [
{id: 1, checkin_time: "2030-05-05 10:22:02"}, // 10 AM.
{id: 2, checkin_time: "2030-05-05 08:22:02"} // 8 AM.
]
console.log(input);
// Closest From Now.
const closestFromNow = times => times.filter(x => Date.now() < new Date(x.checkin_time)).sort((a, b) => new Date(a.checkin_time)*1 - new Date(b.checkin_time)*1)[0]
// Output.
const output = closestFromNow(unfinished)
const output2 = closestFromNow(input)
// Proof.
console.log(output) // Undefined
console.log(output2) // ID 2. 8 AM.
}
}
答案 7 :(得分:0)
关键字static
表示对象的成员(在这种情况下为字段)没有绑定到类的实例,而是对象的成员。如果静态成员是字段,则在加载类时对其进行初始化。
可通过类而不是通过实例进行访问(尽管后者并非不可能,但被认为是错误的形式),因此可以在没有构造函数运行的情况下进行访问。
关键字final
应用于对象的字段时,意味着只能被分配一次,并且在初始化期间必须被分配。
这两个关键字一起有效地定义了一个常数:它只能分配一次,必须分配,并且对于该类的所有实例都是相同的。
由于静态字段是在类加载期间初始化的,因此必须在声明时或在静态初始化程序块中对其进行初始化。
这意味着,当您到达构造函数时,它将已经被初始化,因为需要已经被初始化。
如果您要查找只分配一次但多次读取的类成员,则您正在处理a singleton。单例模式通常用于访问共享资源。
该字段为静态字段,但不是最终字段;而是在访问该字段时,代码将检查它是否已经初始化,如果尚未初始化,则在此完成。请注意,在具有多个线程的环境中,您需要同步对该字段的访问,以避免在初始化时对其进行访问。