假设我有这样的情况。
private final A a;
private final B b;
private final C c;
private ClassX(){
this.c = createCSomehow();
}
public ClassX(A a){
this();
this.a = a;
this.b = null;
}
public ClassX(B b) {
this();
this.b = b;
this.a = null;
}
为什么Idea会抱怨a和b属性? Idea强调它们并说:变量a可能尚未初始化。我确信我没有更多的构造函数,并且在每种情况下都会填充一些值。
答案 0 :(得分:2)
我真的不知道如何正确回答为什么(需要JLS调查),但对于如何,以下内容应该编译:
private final A a;
private final B b;
private final C c = createCSomehow();
public Main(A a){
this.a = a;
this.b = null;
}
public Main(B b) {
this.b = b;
this.a = null;
}
答案 1 :(得分:2)
根据JLS规范 http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.3.1.2
必须在声明它的类的每个构造函数(第8.8节)的末尾明确赋值空白的最终实例变量(第16.9节);否则会发生编译时错误。 这就是Idea抱怨的原因。
答案 2 :(得分:0)
如果调用不带参数的构造函数,c是唯一被初始化的对象变量。对象变量a和b仅在带参数的构造函数中初始化。所以修复应该如下?
final A a;
final B b;
final C c = createCSomehow();
public ClassX() {
a = null;
b = null;
}
public ClassX(A a) {
this.a = a;
b = null;
}
public ClassX(B b) {
a = null;
this.b = b;
}
答案 3 :(得分:0)
如其他答案所述,离开构造函数后,必须初始化最终字段。因此,提供一个构造函数来初始化所有字段并由private ClassX(A a, B b) {
this.a = a;
this.b = b;
this.c = createCSomehow();
}
public ClassX(A a){
this(a, null);
}
public ClassX(B b) {
this(null, b);
}
构造函数重用它以提供具体值。喜欢这段代码:
-- temporary table like your data ------------
DECLARE @account_fans TABLE(brand NVARCHAR(10),account NVARCHAR(10),fans INT)
INSERT INTO @account_fans VALUES ('Ford', 'ford_uk',10),('Ford', 'ford_uk',11),
('Ford', 'ford_us',20),('Ford', 'ford_us',21),('Jeep', 'jeep_uk',30),
('Jeep', 'jeep_uk',31),('Jeep', 'jeep_us',40),('Jeep', 'jeep_us',41)
-- temporary table like your data ------------
SELECT * FROM @account_fans -- your table
SELECT brand, SUM(fans) fans FROM (
SELECT brand,account,MAX(fans) fans FROM @account_fans GROUP BY account,brand
) A GROUP BY brand -- output you require
答案 4 :(得分:0)
正如Jeremy在评论中所说,可能会有一些代码调用private
构造函数而不是预期的public
构造函数。
关于修复,我更喜欢一种模式,其中1(private?)构造函数设置所有变量,而其他附加构造函数调用此“main”构造函数,例如:
private ClassX(A a, B b){
this.a = a;
this.b = b;
this.c = createCSomehow();
}
public ClassX(A a){
this(a, null);
}
public ClassX(B b) {
this(null, b);
}
答案 5 :(得分:0)
在java中,所有final字段必须初始化为某个值。它们只能在声明它们的位置或构造函数中赋值一次。 如果某些final字段未使用声明进行初始化,那么它应该在所有构造函数中初始化。