Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何强制子类在编译时初始化超类属性?_Java_Jsf - Fatal编程技术网

Java 如何强制子类在编译时初始化超类属性?

Java 如何强制子类在编译时初始化超类属性?,java,jsf,Java,Jsf,我有一个抽象超类,其属性必须由子类设置,以便正确操作实例 abstract SuperClass { // this list must be initialized by the subclass List<? extends SavedSearch> savedSearches; } 。。。但这似乎很奇怪,子类实现者没有义务在方法实现中做任何事情,他们什么也做不了 我知道我可以编写一些运行时检查代码,以确保在超类中运行代码之前savedSearch列表已初始化,但我希望

我有一个抽象超类,其属性必须由子类设置,以便正确操作实例

abstract SuperClass {
  // this list must be initialized by the subclass
  List<? extends SavedSearch> savedSearches;
}
。。。但这似乎很奇怪,子类实现者没有义务在方法实现中做任何事情,他们什么也做不了

我知道我可以编写一些运行时检查代码,以确保在超类中运行代码之前savedSearch列表已初始化,但我希望编译时检查(类似于抽象方法)而不是运行时检查

我看到了一个类似问题的C#答案,该问题建议隐藏默认(零arg)构造函数,并在需要列表作为arg的抽象类中创建一个构造函数。对于Java来说,这听起来也不错。但我的特定类是一个JSF1.x托管bean。我是一个JSF新手,但要让JSF调用托管bean的非标准构造函数,恐怕没有简单的方法

有没有一种方法可以让我在编译时得到一些帮助,以确保实现的子类正确地初始化了超类属性

谢谢

  • 加里

其中一种方法是提供一个将其作为参数的构造函数

public abstract class SuperClass {

    private List<SavedSearch> savedSearches;

    protected SuperClass(List<SavedSearch> savedSearches) {
        this.savedSearches = savedSearches;
        // You can do additional checks here on null, size(), etc.
    }

}

为什么不把初始化代码放在超类的构造函数中,然后在初始化子类时调用
super(…)
。这是一个JSFbean,因此依赖项由框架提供。构造函数时不提供这些依赖项。有问题的列表需要一个到init的数据库连接(在构造之后提供)。不过,更重要的是,我不希望我的超类构造函数执行init。它不知道如何初始化属性,这是实现子类的工作。它们将以不同的方式初始化列表。这就是我所说的“由子类来确保列表正确初始化”的意思。像这样传递数据库连接是一种非常糟糕的做法。查找DAO模式或转到EJB/JPA.BalusC:子类需要依赖项来完成其工作。它需要一把刀。在别处实例化并注入到类中。这是很好的做法。构造函数在依赖注入发生之前运行(除非您通过构造函数进行注入,而我们没有这样做,而且可能无法这样做)。耶,这就是我所指的C#答案。对于一般情况来说,这是一个很好的答案。但它不适用于这种情况(JSF管理的bean)。至少我不这么认为,我需要更多地了解JSF来明确回答这个问题,但我怀疑JSF不允许您使用需要参数的非默认构造函数创建托管bean。它肯定适用于JSF。它将调用
子类
bean的默认构造函数。请注意,您不能将像
SuperClass
这样的抽象类设置为托管bean。所以不要让你被这搞糊涂了。试着自己体验一下:)啊,我明白了。我不理解initAndGetSavedSearchSomeHow()方法返回一个提供给超类非默认构造函数的列表。巴卢斯克:我想我已经消化了你的建议。但我仍然不清楚这有什么帮助。超类可以创建一个1-arg构造函数,子类可以在自己的默认(零arg)构造函数中调用它。这很清楚。但是编译时不能保证子类的默认构造函数调用了超类的1-arg构造函数,对吗?如果子类的默认构造函数不
super()
超类的构造函数,那么类就不会编译。
public abstract class SuperClass {

    private List<SavedSearch> savedSearches;

    protected SuperClass(List<SavedSearch> savedSearches) {
        this.savedSearches = savedSearches;
        // You can do additional checks here on null, size(), etc.
    }

}
public class SubClass extends SuperClass {

    public SubClass() {
        super(initAndGetSavedSearchesSomehow());
    }

}