我有一个使用外部库调用各种web服务的项目。这个库给我这样的对象:
public static class ObjA {
@XmlElement(name = "counter", required = true)
protected BigInteger counter;
@XmlElement(name = "data", required = true)
protected String data;
[...]
}
和此:
public static class ObjB {
@XmlElement(name = "counter", required = true)
protected BigInteger counter;
@XmlElement(name = "data", required = true)
protected String data;
[...]
}
你可以看到objA和objB具有相同的属性,所以,如果我必须同时使用它们,我将重复代码:
public class myClass {
[...]
private ObjA a;
private ObjB b;
[...]
public void myClass() {
[...]
this.a = new ObjectFactory().createObjA();
this.b = new ObjectFactory().createObjB();
[...]
}
public void init() {
this.initA();
this.initB();
}
private void initA() {
this.a.setCounter(BigInteger.ZERO);
this.a.setData = "";
}
private void initB() {
this.b.setCounter(BigInteger.ZERO);
this.b.setData = "";
}
[...]
}
initA和initB是完全相同的,我无法访问库代码所以我无法创建一个通用接口,我可以通过哪种方式避免重复代码?我的意思是,有可能有这样的东西吗?
private void initObj([ObjA|ObjB] obj) {
obj.setCounter(BigInteger.ZERO);
obj.setData = "";
}
谢谢! Muchas Gracias!
附录
请注意我无权访问底层库,因此我无法以任何方式添加修改类,接口,wsdl或xsd。 另外在我看来,如果我使用ws或不使用ws,jaxb或其他库是不重要的:你可以想象没有注释的ObjA和ObjB,如下所示:
public static class ObjA {
protected BigInteger counter;
protected String data;
[...]
}
public static class ObjB {
protected BigInteger counter;
protected String data;
[...]
}
并且问题的关键不会改变。
答案 0 :(得分:1)
我想您正在使用JAXB。您可以阅读对象列表。 请参阅此帖子:JAXB Unmarshalling: List of objects
答案 1 :(得分:1)
我假设使用某种工具为你生成类,也许是maven cxf-codegen-plugin等。 如果是这种情况,则需要修改WSDL和XSD,以便生成令您满意的DTO类。 如果为您提供了WSDL,那么您只需按原样接受该服务吗?
如果您知道常用方法都具有相同的名称,您可以使用反射吗?
所以你要用原始反射来做这样的事情:
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void initObject(Object o) throws Exception {
if (!(o instanceof ObjA)&&!(o instanceof ObjB)) return;
Method m = o.getClass().getMethod("setCounter",java.math.BigInteger.class);
m.invoke(o,BigInteger.ZERO);
m = o.getClass().getMethod("setData",java.lang.String.class);
m.invoke(o,"");
}
public static void main(final String[] args) throws Exception {
List<Object>objects = new ArrayList<Object>();
//this is like your factory method
Object o = Class.forName("ObjA").newInstance();
initObject(o);
objects.add(o);
o = Class.forName("ObjB").newInstance();
initObject(o);
objects.add(o);
}
}
如果您想使用库,可以使用类似JXPath和see docs here的内容 但我觉得为了你的目的,原始反思可能很好。不需要大规模复杂的反射库。
答案 2 :(得分:0)
由于他们没有共同的接口(或父类?),我想要走的路是使用java反射。
自己创建一些反射辅助方法,例如&#34; init(Class clazz)&#34;并调用建设者。
请记住,在大多数情况下,java反射是不好的做法,因此请确保没有其他/更好的方法来实现您的目标。