替代构造函数返回 null

Alternative to constructor returning null

我目前正在为我的公司创建一个大项目,其中包含大量数据结构和 shizle。我正在为我的以下问题寻找一个好的解决方案:

因为 Java 不可能有一个构造函数 return null(至少我的研究是这么说的)我需要一个好的替代品。

假设我有以下代码(只是一个例子。实际项目更复杂):

public abstract class SuperClass
{
    public SuperClass(Element element)
    {
        if(element != null)
            readElement(element);
    }

    public abstract void readElement(Element element);
}

public class Foo extends SuperClass
{
    private Bar bar1;
    private Bar bar2;
    private Bar bar3;
    //...

    public Foo(Element element)
    {
        super(element);
    }

    @Override
    public void readElement(Element element)
    {
        this.bar1 = new Bar(element.getChild("bar1"));
        this.bar2 = new Bar(element.getChild("bar2"));
        this.bar3 = new Bar(element.getChild("bar3"));
        //...
    }
}

public class Bar extends SuperClass
{
    private String value;

    public Bar(Element element)
    {
        super(element);
    }

    @Override
    public void readElement(Element element)
    {
        this.value = element.getChildText("value");
    }
}

Element.getChild(String name) 函数来自 jdom2 (XML-Parser),用于读取 xml 文件。如果未找到具有给定名称的 child,它可以并且将 return 为空。 我在这个例子的基础上编写了我的项目,愚蠢地认为,如果命名函数 returns 为 null,则变量(例如此处的 bar1)也将为 null。但是由于命名函数被 "new Bar(...)" 包裹,它不会为 null,而是一个空的 object。 但我希望并且需要 "empty" 变量为 null,因此在遍历项目中的所有数据结构时我可以轻松跳过这些变量。 我会将 returned Object 从 "getChild(...)" 函数保存到一个局部变量 "lElement" 中,然后有类似的东西:

if(lElement != null)
    bar1 = lElement;

但是我有超过 50 种不同的数据结构,就像我的示例中的那些数据结构以及它们中的足够多的变量,它们由 "readElement(...)" 函数初始化。这个想法需要太多的编辑,甚至可能需要相当多的性能。对我来说似乎也有点... "ugly"。至少对于这个数量的变量。所以我需要一些东西,它对性能没有任何影响,而且很容易,就像让构造函数 return 为 null 一样。我不想更改这些函数中的太多代码。 如果 "Element element" 等于 null,我也有让 Datastructure 将自身设置为 null 的想法,但经过快速研究后,这个想法马上就被抹杀了 ^^。 object 删除自己是行不通的,也不符合逻辑。

所以基本上我可以自己解决这个问题。但这可能不是最有效的方法。无论是在编辑代码还是在 code-performance 中。 所以我问你们,你们将如何解决这个问题。不仅像我的例子中的两个简单的数据结构,而是 50 类+ 使用这个系统的回想。

我希望你能帮助我,如果英语不好,我深表歉意。我来自德国^^。 到目前为止,我已经使用 Java 编写代码超过 5 年(自去年以来 "professionally"),所以这对我来说有点尴尬,之前没有想到这个问题。但现在要回到完全不同的事情上已经太晚了。

提前致谢!

返回 null 的构造函数的替代方法是返回 null.

的工厂方法

虽然不会写

class SomeClass {
    public SomeClass(Node node) {
        if (node.isEmpty()) return null; // Does not compile
        ...
    }
}

你当然可以这样写:

class SomeClass {
    private SomeClass(Node node) {
        // Self-check: this should never happen
        if (node.isEmpty()) {
            throw new IllegalArgumentException("node");
        }
        ...
    }
    public static SomeClass makeFromNode(Node node) {
        if (node.isEmpty()) {
            return null;
        }
        return new SomeClass(node);
    }
}

将构造函数调用替换为对 makeFromNode 的调用将使您能够以简单统一的方式处理节点为 null 的情况。

构造函数定义任意对象的初始化。因此他们永远无法 return 值。

我认为缺少 hasElement 方法是一个主要的设计缺陷,但是如果您坚持 returning null,您可以。

在任何情况下,您都应该利用泛型和方法引用 (>= Java 8)。

您可以使用代码示例中的 wrap 方法来满足您给定的要求(使用继承让 sub 类 更容易阅读 children)。

public void readElement(Element element) {
    this.bar1 = wrap(element.getChild("bar1"), Bar::new);
    this.bar2 = wrap(element.getChild("bar1"), Bar::new);
    this.bar3 = wrap(element.getChild("bar1"), Bar::new);
}

protected <T> T wrap(Element element, Function<Element, T> elem) {
    if (element == null) {
        return null; // Not a good value
    }
    return elem.apply(element);
}