【问题标题】:Blank final fields are not initialized when using a super()-constructor使用 super() 构造函数时未初始化空白最终字段
【发布时间】:2021-04-01 01:06:50
【问题描述】:

诚然,我对面向对象编程有点陌生,因此非常感谢您的帮助! 我有一个类“Gerade”(德语为直线)和一个类“Strahl”(德语为射线)。我想在子类“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;
    }   
}

“Gerade”类使用“Punkt”类的某些属性和方法。坐标是 BigDecimals。以免您感到困惑。


public class Strahl extends Gerade 
{
    

    private final Punkt p1;
    private final Punkt p2;
    private final Punkt start;


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

    }

【问题讨论】:

  • 我不会说德语,但您的第一次检查似乎试图阻止您两次通过同一点。与其打印一条消息(容易忽略)并清空字段(一旦使用它就使构造的实例无用),而是抛出异常
  • Smite - 如果其中一个答案解决了您的问题,您可以通过将其标记为已接受来帮助社区。接受的答案有助于未来的访问者自信地使用该解决方案。要mark an answer as accepted,您需要单击答案左侧的大复选标记 (✓)。 注意:您只能接受一个问题的答案。但是,一旦您拥有超过 15 个声望点,您就可以upvote 任意数量的答案。

标签: java constructor subclass super superclass


【解决方案1】:

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

【讨论】:

  • 好的,我再看一遍。非常感谢!
【解决方案2】:

您的类Gerade 中已经有两个Punkt 实例变量。所以你不需要在课堂上重复它们Strahl

其实这是问题之一:Strahl中的final变量p1p2没有在任何地方初始化!

所以,只需删除它们:

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

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

【讨论】:

    【解决方案3】:

    既然您调用的是super(a, b),那么您没有理由在Strahl 中重新声明它们。不用写p1.equals(p2) == true,你可以直接写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 是一种非常好的做法。您不应该鼓励他们删除 final 关键字。
    • 嗯......现在,如果你看到了,我已经回答了。 ;-)
    • @Seelenvirtuose - 是的?。
    猜你喜欢
    • 1970-01-01
    • 2017-06-05
    • 2015-05-21
    • 2011-07-02
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 2017-12-01
    相关资源
    最近更新 更多