-
10-10-2019 - |
题
给定以下三个类,我如何使用反射来调用父类的初始化函数,然后拨打子类:
public class Test {
public static void main(String[] args) {
ExtendedElement ee = new ExtendedElement();
initialize(ee);
}
public static void initialize(Element element) {
System.out.println(element.getClass());
initialize(element.getClass());
}
public static void initialize(Class clazz) {
System.out.println(clazz.getClass());
}
}
public class Element {
protected String value;
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
public class ExtendedElement extends Element {
protected String extendedValue;
public void setExtendedValue(String extendedValue) {
this.extendedValue = extendedValue;
}
public String getExtendedValue() { return extendedValue; }
}
我不太确定如何在测试类中使用初始化函数,因为Clazz参数是一种原始类型。
我的本质上需要的是,如果我传递到的初始化是元素的子类,则将类层次结构调用。
如下所示:
public void initialize(Class clazz) {
if (Element.class.isInstance(clazz.getClass().getSuperclass()) {
initialize(clazz.getClass().getSuperclass());
}
//Work to call initialize function
}
编辑1:
我不能以不同的方式参数化上述伪函数以保留对象的类型,然后调用我需要的功能?
我要做的是避免必须对我的每个课程覆盖相同的方法,并允许对我的Selenium 2页面对象进行一些继承。我需要做的是能够在这些字段上运行测试之前,是我自我的超级类(ES)的内省。
这些注入了春季,为了使我允许使用春季表达语言编写测试的事物更复杂。我正在懒洋洋地加载豆子,并使用初始化界面来尝试在使用之前初始化我的webelements以避免使用NPE。
我必须用自定义对象包装插头,以便我可以使用弹簧注入位置策略(我们重复使用很多件,但是它们具有不同的ID /类名称,取决于应用程序中使用的位置;这是事先完成的对我来说,到达这里,尽管我争论一致性,但此时不会改变。例如,我们有一个约会小部件具有不同的粒度,有时我们只需要一个月,有时和每年等等……如果我可以使用抽象类并将这些共同点打破到它们最不常见的分母,那就太好了并从那里延伸。为此,我需要能够在我的基类中进行以下操作:
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
//Pass in concrete impl we are working with - this allows me to initialize properly
initializeWebElements(this.getClass());
}
...
public void initializeWebElements(Class clazz) {
//This does not grab inherited fields, which also need to be initialized
for (Field field : clazz.getDeclaredFields()) {
if (WidgetElement.class == field.getType()) {
Method getWidgetElement = clazz.getDeclaredMethod("get" +
StringUtils.capitalize(field.getName()), new Class [] {});
WidgetElement element =
(WidgetElement) getWidgetElement.invoke(this, new Object [] {});
element.initElement();
}
}
解决方案 3
这是我的临时解决方案,让问题开放,希望为我的用例收集一些更好的答案。
public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
Class clazz = this.getClass();
do {
initializeElements(clazz);
clazz = clazz.getSuperclass();
} while (clazz != null);
}
其他提示
您不能以特定级别调用方法。唯一的是您可以访问 super
集体本身的关键字。
为了做这项工作,您想打电话给 super.initialize()
从每个子类内部,然后通过反射调用。
这不是C ++,您在哪里 能够 在继承层次结构的特定级别上调用特定方法。
我不太确定如何在测试类中参数化初始化函数,因为Clazz参数是一种原始类型。
您的示例中没有任何内容要求您使用通用类型参数,因此将其声明为 Class<?>
.
我不明白您的初始化方法真正要做什么,但是有很多问题:
你似乎有一个 initialize
使用实例的方法( Element
)作为一个论点,另一个是 Class
对象作为参数。那真的是苹果和橙色的东西...您需要解释自己要做的事情。
您尝试使用该方法包含以下方式:
Element.class.isInstance(clazz.getClass().getSuperclass())
这将永远不会评估为true,因为它在询问是否有些 Class
对象是一个 实例 的 Element
班级。 (更, clazz.getClass().getSuperclass()
实际上将与 java.lang.Object.class
. 。一个班级 Class
对象是 java.lang.Class
它的超类是 java.lang.Object
).
但是我无法弄清楚它应该是什么,因为您没有清楚地描述要实现的目标。