Java 使用super()构造函数时,不会初始化空白的final字段

Java 使用super()构造函数时,不会初始化空白的final字段,java,constructor,subclass,super,superclass,Java,Constructor,Subclass,Super,Superclass,诚然,我对面向对象编程有点陌生,因此非常感谢您的帮助! 我有一个班“Gerade”(德语代表直线)和一个班“Strahl”(德语代表ray)。我想在子类“Strahl”中调用超类“Gerade”的构造函数。但现在我得到了错误:“空白的最终字段p1[和p2]可能尚未初始化”。这是什么原因?我非常感谢你的回答。提前谢谢你 public class Gerade { private final Punkt p1; private final Punkt p2; public Gerade

诚然,我对面向对象编程有点陌生,因此非常感谢您的帮助! 我有一个班“Gerade”(德语代表直线)和一个班“Strahl”(德语代表ray)。我想在子类“Strahl”中调用超类“Gerade”的构造函数。但现在我得到了错误:“空白的最终字段p1[和p2]可能尚未初始化”。这是什么原因?我非常感谢你的回答。提前谢谢你


public class Gerade {
    
private final Punkt p1;
private final Punkt p2;

public Gerade(Punkt p1, Punkt p2)
{
    if(p1.equals(p2)==true)
    {
    System.out.println("Die Eingabe ist ungueltig. Beide Punkte haben die selben Koordinaten.");
    p1 = null;
    p2 = null;
    }
    

    if(p1.getXkoord().equals(p2.getXkoord())==true)
    {
        if((p1.getYkoord().compareTo(p2.getYkoord()) < 0))
        {
            this.p1 = p1;
            this.p2 = p2;
        }
        else
        {
            this.p1 = p2;
            this.p2 = p1;
        }
    }    
    
    else if((p1.getXkoord().compareTo(p2.getXkoord()) > 0))
    {
        this.p2 = p1;
        this.p1 = p2;
    }
    
    else 
    {
        this.p1 = p1;
        this.p2 = p2;
    }   
}

p1和p2应在Gerade的构造函数执行后初始化。但由于复杂的控制流,编译器不能保证这会发生。仔细查看您的条件-如果不满足任何条件,您必须提供回退

执行Gerade构造函数后,p1和p2都应初始化。但由于复杂的控制流,编译器不能保证这会发生。仔细查看您的条件-如果任何一个条件都不满足,您必须提供回退

您的类中已经有两个
Punkt
实例变量
Gerade
。因此,您不需要在类中重复它们
Strahl

事实上,这是问题之一:Strahl中的最终变量
p1
p2
没有在任何地方初始化

因此,只需删除它们:

public class Strahl extends Gerade {
    private final Punkt start;
    public Strahl(Punkt a, Punkt b) {
        super(a, b);
        this.start = a;
    }
}

另一个问题是@KonstantinPribluda在他的回答中提到的。

您的类中已经有两个
Punkt
实例变量
Gerade
。因此,您不需要在类中重复它们
Strahl

事实上,这是问题之一:Strahl中的最终变量
p1
p2
没有在任何地方初始化

因此,只需删除它们:

public class Strahl extends Gerade {
    private final Punkt start;
    public Strahl(Punkt a, Punkt b) {
        super(a, b);
        this.start = a;
    }
}

另一个问题是@KonstantinPribluda在他的回答中提到的。

既然您正在调用
super(a,b)
,那么您没有理由在
Strahl
中重新声明它们。您可以简单地编写
p1.equals(p2)
,而不是编写
p1.equals(p2)

它可以是

class Gerade {

    private final Punkt p1 = null;
    private final Punkt p2 = null;

    public Gerade(Punkt p1, Punkt p2) {
        if (p1.equals(p2)) {
            System.out.println("Die Eingabe ist ungueltig. Beide Punkte haben die selben Koordinaten.");
            p1 = null;
            p2 = null;
        }

        // ...
    }
}

class Strahl extends Gerade {

    private final Punkt start;

    public Strahl(Punkt a, Punkt b) {
        super(a, b);
        this.start = a;
    }
}

我还建议您仅在初始化时使用构造函数,任何业务逻辑都应该重构为某些方法。

因为您正在调用
super(a,b)
,所以没有理由在
Strahl
中重新声明它们。您可以简单地编写
p1.equals(p2)
,而不是编写
p1.equals(p2)

它可以是

class Gerade {

    private final Punkt p1 = null;
    private final Punkt p2 = null;

    public Gerade(Punkt p1, Punkt p2) {
        if (p1.equals(p2)) {
            System.out.println("Die Eingabe ist ungueltig. Beide Punkte haben die selben Koordinaten.");
            p1 = null;
            p2 = null;
        }

        // ...
    }
}

class Strahl extends Gerade {

    private final Punkt start;

    public Strahl(Punkt a, Punkt b) {
        super(a, b);
        this.start = a;
    }
}


我还建议您只在初始化时使用构造函数,任何业务逻辑都应该重构为一些方法。

好的,我会再看一遍。谢谢!好的,我再看一遍。谢谢!我修好了,谢谢!不客气!祝你成功!将实例变量声明为final是一个非常好的实践。您不应该鼓励他们删除最后一个关键字。@seelenvirtuse-谢谢。更正了。嗯。。。现在,如果你知道的话,我已经回答了我修好了,谢谢!不客气!祝你成功!将实例变量声明为final是一个非常好的实践。您不应该鼓励他们删除最后一个关键字。@seelenvirtuse-谢谢。更正了。嗯。。。现在,如果你知道的话,我已经回答了现在可以了,非常感谢!现在可以了,非常感谢!我不会说德语,但看起来你的第一张支票是想阻止你在同一点上通过两次。与其打印一条消息(很容易忽略)并清空字段(一旦您开始使用构造的实例,它就会变得无用),不如抛出一个异常来代替代替Headsmite——如果其中一个答案解决了您的问题,您可以通过将其标记为已接受来帮助社区。公认的答案有助于未来的访问者自信地使用解决方案。要进行此操作,您需要单击大复选标记(✓) 答案左边。注意:一个问题只能接受一个答案。但是,一旦你有15+个信誉点,你就可以随心所欲地回答。我不会说德语,但看起来你的第一张支票试图阻止你两次传递同一点。而不是打印一条消息(很容易忽略)并清空字段(一旦您开始使用构造的实例,它将变得无用),抛出一个异常而不是代替它-如果其中一个答案解决了您的问题,您可以通过将其标记为已接受来帮助社区。已接受的答案有助于未来的访问者自信地使用该解决方案。为此,您需要单击大复选标记(✓) 在答案的左边。注意:一个问题只能接受一个答案。但是,一旦你有15+个信誉点,你可以根据自己的意愿选择任意多个答案。