对于模糊的标题感到抱歉;我不完全确定问题是什么。
简而言之:某个基类的子类必须定义 3个特定的静态方法,隐藏基类的静态方法。实现描述类在初始化时检查它。然而,在运行应用程序时看似随意,我在初始化期间得到运行时异常,说我没有正确地重新实现这些方法。但是当我发生这种情况时,我正在其他地方的不相关的类中工作,就像它一样,并且简单地改变方法的顺序将其修复了很长时间。
所以,有三个类:Base,Derived和AlgImplementation类:
AlgImplementation构造函数:
/* verifying that the extending class has implemented these methods */
if (this.getAlgorithmClassName() == null) {
throw new IllegalArgumentException("The Algorithm Class of this algorithm has not re-implemented the getAlgorithmClassName() method from as specified.");
}
if (this.getAlgorithmClassDescription() == null) {
throw new IllegalArgumentException("The Algorithm Class of this algorithm has not re-implemented the getAlgorithmClassDescription() method from as specified.");
}
if (this.getAlgorithmClassAnalyticLevel() == null) {
throw new IllegalArgumentException("The Algorithm Class of this algorithm has not re-implemented the getAlgorithmClassAnalyticLevel() method from as specified.");
}
这就是问题发生的地方之一,其中一项检查失败了。我从上面的一个或多个中得到了IllegalArgumentException。我可以简单地在派生类中移动实现的顺序,强制重建该代码,然后它可以正常工作。
Base&派生类都具有相同的简单静态方法,但它们返回的静态字段的定义不同:
class Derived extends Base {
public static AnalyticLevel getAlgorithmClassAnalyticLevel()
{
return ANALYTIC_LEVEL;
}
public static String getAlgorithmClassName()
{
return NAME;
}
public static String getAlgorithmClassDescription()
{
return DESCRIPTION;
}
}
以上字段都是非null静态最终字符串。
现在,在Derived类中,我声明了一个静态的最终AlgImplementation字段: public static final AlgImplementation derivedAlg = new AlgImplementation(“xyz”,Derived.class,“Our XYZ derived class”,“”);
最后,我认为您需要知道的最后一件事是,这个AlgImplementation实例为每个静态方法类执行此操作:
public String getAlgorithmClassName() {
String className = "";
try {
className = (String)algorithmClass.getDeclaredMethod("getAlgorithmClassName", new Class<?>[0]).invoke(null, new Object[0]);
} catch (Exception e) {
throw new UnsupportedOperationException("Required static method getAlgorithmClassName() not implemented on "+this.getClass().getName());
}
return className;
}
所以,我的问题是:如果事实上声明了这些方法,那么对派生方法的检查怎么会失败呢?是否存在声明静态AlgImplementation字段的问题,该字段引用了它所定义的类(导致一些奇怪的编译问题,或类似的东西)?
错误发生在Derived类的初始化期间,特别是在初始化静态AlgImplementation字段的行中,这就是为什么我认为在Derived类本身可能存在这样做的原因。
答案 0 :(得分:1)
我怀疑问题是由于类的静态最终字段的初始化顺序。通过在类初始化期间使用反射,您可以在完全初始化之前访问该类。如果在派生类上,您有以下内容:
public static final String NAME;
static {
NAME = "some name";
}
public static final AlgImplementation derivedAlg =
new AlgImplementation("xyz", Derived.class, "Our XYZ derived class", "");
然后AlgImplementation将在初始化之后检查NAME常量,并将读取“some name”字符串。如果您颠倒顺序:
public static final AlgImplementation derivedAlg =
new AlgImplementation("xyz", Derived.class, "Our XYZ derived class", "");
public static final String NAME;
static {
NAME = "some name";
}
然后AlgImplementation将在分配之前读取常量,并将改为读取null
。
如果NAME直接由编译时常量分配,我不确定是否可能发生这种情况:
public static final String NAME = "some name";
我猜这会阻止这个问题,但也许不会。你的声明“改变方法的顺序将其修复了很长时间”支持了这个问题是由于初始化顺序的想法。我建议在所有其他常量之后移动derivedAlg
字段,以鼓励它最后被初始化。
答案 1 :(得分:0)
静态方法不参与类层次结构。您应该始终使用staticMethod()
或Class.staticMethod()
。