我正在编写一个需要一些最终变量的java程序。 java类必须是单例对象。我无法直接初始化最终变量。这是我的代码:
public class Car {
private Price price = null;
//Constructor
public Car(Price p) {
this.price = p;
}
//method to get the singleton
private static Car instance = null;
public static Car getInstance(Price p) {
if(instance == null) {
instance = new ExcelUtil2(p);
}
return instance;
}
//declare & initialize final variable
private final Wheel WHEEL_TYPE = getWheelType();
//get value of the final variable
public Wheel getWheelType() {
Wheel wheel = Car.createWheel();
if(price.getAmount() > 30000){
wheel.setWheelType("Alloy");
}else{
wheel.setWheelType("Alluminium");
}
return wheel;
}
}
我想知道我是否可以这样做:
private final Wheel WHEEL_TYPE = getWheelType();
这是我的第一个问题。
接下来就是,当我运行它时,我得到nullPointerException:
price.getAmount()
在public Wheel getWheelType()
方法中。
我正在使用公共构造函数初始化价格。
我在其他类中启动了这个类:
Car car = Car.getInstance(price);
在这里,我验证了price对象和price.getAmount()都不为空。
任何人都可以指导我做错了什么吗? 感谢
答案 0 :(得分:5)
没有任何内在错误
private final Wheel WHEEL_TYPE = getWheelType();
一般情况下,(按照the Java tutorial中的建议),当你这样做时,你应该调用无法覆盖的方法 - final
方法,static
方法, private
方法或final
类中的方法。
但是,使用您的特定代码存在问题。在执行getWheelType()
时,您正在调用price.getAmount()
并在构造函数的主体中初始化price
。不幸的是,对于您的设计,字段实例初始值设定项在构造函数的主体之前执行,因此在price.getAmount()
初始化之前,您最终会调用price
。
我建议您在分配到WHEEL_TYPE
后,只需将作业移至price
到构造函数内部。
答案 1 :(得分:1)
始终允许您初始化最终变量。编译器 确保你只能做一次。
答案 2 :(得分:1)
正如Ed所说,你的价格是一个实例变量,它在实例方法getWheelType()中使用,这是正常的。但问题是这个方法用于创建最终变量。在分配实例变量p之前分配最终变量。
如果您真的想拥有代码结构,可以考虑使用Builder模式。我的代码没有得到很好的考虑,但它会是这样的。
public class CarTwo {
private Price price = null;
private Builder b;
public Builder getBuilder(){
return b;
}
private final Wheel WHEEL_TYPE;
private CarTwo(Builder b) {
this.b = b;
this.price = b.getPrice();
WHEEL_TYPE = b.getWheelType();
}
private static CarTwo instance = null;
public static CarTwo getInstance(Builder builder) {
if(instance == null) {
instance = new ExcelUtil2(builder);
}
return instance;
}
public static class Builder{
private Price pr;
public Builder(Price price){
pr = price;
}
public Price getPrice(){
return pr;
}
public Wheel getWheelType() {
Wheel wheel = CarTwo.createWheel();
if(pr.getAmount() > 30000){
wheel.setWheelType("Alloy");
}else{
wheel.setWheelType("Alluminium");
}
return wheel;
}
}
}
然后,您可以像这样创建CarTwo对象:
CarTwo.Builder b = new CarTwo.Builder(new Price());
CarTwo ct = CarTwo.getInstance(b);