Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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_Oop_Code Duplication - Fatal编程技术网

Java:相同的对象,如何避免重复代码

Java:相同的对象,如何避免重复代码,java,oop,code-duplication,Java,Oop,Code Duplication,我有一个使用外部库调用各种Web服务的项目。此库为我提供如下对象: public static class ObjA { @XmlElement(name = "counter", required = true) protected BigInteger counter; @XmlElement(name = "data", required = true) protected String data; [...] } public static cl

我有一个使用外部库调用各种Web服务的项目。此库为我提供如下对象:

public static class ObjA {
    @XmlElement(name = "counter", required = true)
    protected BigInteger counter;
    @XmlElement(name = "data", required = true)
    protected String data;
    [...]
}
public static class ObjA {
    protected BigInteger counter;
    protected String data;
    [...]
}

public static class ObjB {
    protected BigInteger counter;
    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 = "";
    }
谢谢大家!!谢谢你

附录

请注意,我无法访问底层库,因此无法以任何方式添加修改类、接口、wsdl或xsd。 另外,在我看来,如果我使用的是ws或非ws、jaxb或其他库,这并不重要:您可以想象没有注释的ObjA和ObjB,如下所示:

public static class ObjA {
    @XmlElement(name = "counter", required = true)
    protected BigInteger counter;
    @XmlElement(name = "data", required = true)
    protected String data;
    [...]
}
public static class ObjA {
    protected BigInteger counter;
    protected String data;
    [...]
}

public static class ObjB {
    protected BigInteger counter;
    protected String data;
    [...]
}

问题的关键并没有改变。

因为它们没有一个公共接口(或父类?),我想应该使用java反射

自己创建一些反射助手方法,比如“init(Class clazz)”并调用构造函数


请记住,java反射在大多数情况下都是不好的做法,因此请确保没有其他/更好的方法来实现您的目标。

我想您正在使用JAXB。您可以读取对象列表。
请参阅本文:

我假设这些类是使用某种工具为您生成的,可能是maven cxf codegen插件等。 如果是这种情况,您需要修改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);
    }
}
import java.lang.reflect.Method;
导入java.math.biginger;
导入java.util.ArrayList;
导入java.util.List;
公共类测试{
公共静态void initObject(对象o)引发异常{
如果(!(o ObjA实例)和(!(o ObjB实例))返回;
方法m=o.getClass().getMethod(“setCounter”,java.math.biginger.class);
m、 调用(o,biginger.ZERO);
m=o.getClass().getMethod(“setData”,java.lang.String.class);
m、 援引(o)“”;
}
公共静态void main(最终字符串[]args)引发异常{
Listobjects=新的ArrayList();
//这就像你的工厂方法
对象o=Class.forName(“ObjA”).newInstance();
initObject(o);
添加(o);
o=Class.forName(“ObjB”).newInstance();
initObject(o);
添加(o);
}
}
如果您想使用库,可以使用JXPath和
但我认为对于你来说,原始反射可能是好的。不需要一个非常复杂的反射库。

如果您不能创建一个公共接口(在本例中是抽象类),那么无论您做什么,您都必须编写代码来初始化type
ObjA
和type
ObjB
。您可以使用动态方法(反射或BeanUtil)使用相同的方法处理不同的类型。然而,这也有一些自身的问题(静态分析不知道),所以我通常会远离它。我们对上下文一无所知,因此可能还有其他解决方案。别忘了和API提供者谈谈。我只需要制作一个超类,手工编辑生成的(估计每个类只有一个位置),然后制作一个read me和一个视频,说明做了什么和为什么。@tgkprog我不能“手工编辑生成的”,我没有访问源代码的权限。无论如何,我认为如果出于某种原因你不得不重新生成代码,那么强制重新编辑代码是非常糟糕的。这将如何避免像OP的myClass中那样重复代码?请解释!这不是一个对象列表,它们是两个相同的对象,但定义为两个名称,就像我的lillte Book12 my good film24:bookdata和filmdata是相同但不同的对象为了提供更好的帮助,您应该提供更多关于这个问题的信息,比如:您使用JAXB吗?您将调用1个webservice,并使用该响应构建对象A和B?或者他们将从不同的ws-souces获取信息?问题是我无法访问库,也无法访问WSDL、XSD等。。。无论如何,我认为对象是否通过ws并不重要,它们只是两个完全相同的对象,底层是一个接受它们的黑盒子。技术上可行,但当我试图想象“助手方法”的签名和生成的代码时,我微妙地颤抖。编译时错误检查将延迟到运行时。我无法修改WSDL或XSD。我正在考虑反思,但正如@L.Butz所说的,这是一种不好的做法。这通常是一种不好的做法,只是因为很难正确地进行。但实际上,您选择的几乎所有主要java库都使用了反射,尤其是Jackson等。我想不出任何解决问题的方法不涉及某种基于反射的解决方案。您可以尝试xpath之类的方法来为您提供参考,我认为您是对的。你能用一个解决ObjA和ObjB问题的例子来给出答案吗?我在上面添加了一个例子,你可以缓存这些方法,只需执行一次,以后只调用