Java 使用运行时确定的类型创建对象

Java 使用运行时确定的类型创建对象,java,inheritance,design-patterns,io,Java,Inheritance,Design Patterns,Io,我正在编写一个程序,需要保存和加载文件中的各种对象。文件保存为XML,因此我决定为所有可以转换为XML的类创建一个名为“XMLConvertible”的接口。然而,当我读取文件时,我需要根据XML文件的内容创建不同类型的对象 例如: <Component></Component> <Module></Module> 需要首先创建Component类型的对象,然后创建Module类型的对象 到目前为止,我遇到的最干净的方法是使用一个工厂,其中包

我正在编写一个程序,需要保存和加载文件中的各种对象。文件保存为XML,因此我决定为所有可以转换为XML的类创建一个名为“XMLConvertible”的接口。然而,当我读取文件时,我需要根据XML文件的内容创建不同类型的对象

例如:

<Component></Component>
<Module></Module>

需要首先创建Component类型的对象,然后创建Module类型的对象

到目前为止,我遇到的最干净的方法是使用一个工厂,其中包含可从XML文件读取的所有不同类的构建器的静态列表。这样(为了简洁起见,省略了一些信息):

公共接口{
公共无效写入();
公共无效读取();
}
公共抽象类工厂{
私有静态映射xmlConvertibles=newHashMap();
公共静态void addXmlConvertable(字符串键,XmlConvertable值){
xmlConvertibles.put(键,值);
}
公共静态XMLConvertible getXmlConvertible(字符串键){
返回xmlConvertibles.get(key);
}
}
公共类组件实现XMLConvertable{
...
}
公共类ComponentBuilder扩展生成器{
静止的{
Factory.addXmlConvertible(“组件”,新组件生成器);
}
公共组件生成(){…}
}
公共类模块实现了XMLConvertable{
...
}
公共类ModuleBuilder扩展生成器{
静止的{
Factory.addXmlConvertible(“组件”,新组件生成器);
}
公共模块生成(){…}
}
问题是,我必须为我添加的每个新XMLConverable类创建两个类,一个实际类和一个生成器。我想有一种方法强迫自己添加一个构建器,这样我就不会忘记,或者理想地找到一种更干净的方法来实现类似的东西


很抱歉发了这么长的帖子,我试着把它缩短一点。希望还是很容易理解问题所在。

您关心XML的格式吗?有像xstream这样的工具可以序列化为XML,例如

import com.thoughtworks.xstream.XStream;
import java.util.ArrayList;
import java.util.List;

public class Example {

    public static void main(String[] args) {
        XStream xStream = new XStream();

        List<Object> things = new ArrayList<>();
        things.add(new Component("foo"));
        things.add(new Module("bar"));

        String xml = xStream.toXML(things);
        List<Object> things2 = (List<Object>) xStream.fromXML(xml);
    }

    public static class Component {
        private final String componentField;

        public Component(String componentField) {this.componentField = componentField;}
    }

    public static class Module {
        private final String moduleField;

        public Module(String moduleField) {this.moduleField = moduleField;}
    }
}
import com.thoughtworks.xstream.xstream;
导入java.util.ArrayList;
导入java.util.List;
公开课范例{
公共静态void main(字符串[]args){
XStream XStream=新的XStream();
List things=new ArrayList();
添加(新组件(“foo”);
添加(新模块(“条”);
字符串xml=xStream.toXML(things);
List things2=(List)xStream.fromXML(xml);
}
公共静态类组件{
私有最终字符串组件字段;
公共组件(字符串componentField){this.componentField=componentField;}
}
公共静态类模块{
私有最终字符串moduleField;
公共模块(字符串moduleField){this.moduleField=moduleField;}
}
}
在pom中,您需要:

        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.15</version>
        </dependency>

com.thoughtworks.xstream
xstream
1.4.15
这将产生:

<list>
  <Example_-Component>
    <componentField>foo</componentField>
  </Example_-Component>
  <Example_-Module>
    <moduleField>bar</moduleField>
  </Example_-Module>
</list>

福
酒吧

您不需要编写任何特殊的构建器,但XML文件的结构与类的实现相同,因此,如果需要任何跨版本兼容性,则可能很难进行更改。

您关心XML的格式吗?有像xstream这样的工具可以序列化为XML,例如

import com.thoughtworks.xstream.XStream;
import java.util.ArrayList;
import java.util.List;

public class Example {

    public static void main(String[] args) {
        XStream xStream = new XStream();

        List<Object> things = new ArrayList<>();
        things.add(new Component("foo"));
        things.add(new Module("bar"));

        String xml = xStream.toXML(things);
        List<Object> things2 = (List<Object>) xStream.fromXML(xml);
    }

    public static class Component {
        private final String componentField;

        public Component(String componentField) {this.componentField = componentField;}
    }

    public static class Module {
        private final String moduleField;

        public Module(String moduleField) {this.moduleField = moduleField;}
    }
}
import com.thoughtworks.xstream.xstream;
导入java.util.ArrayList;
导入java.util.List;
公开课范例{
公共静态void main(字符串[]args){
XStream XStream=新的XStream();
List things=new ArrayList();
添加(新组件(“foo”);
添加(新模块(“条”);
字符串xml=xStream.toXML(things);
List things2=(List)xStream.fromXML(xml);
}
公共静态类组件{
私有最终字符串组件字段;
公共组件(字符串componentField){this.componentField=componentField;}
}
公共静态类模块{
私有最终字符串moduleField;
公共模块(字符串moduleField){this.moduleField=moduleField;}
}
}
在pom中,您需要:

        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.15</version>
        </dependency>

com.thoughtworks.xstream
xstream
1.4.15
这将产生:

<list>
  <Example_-Component>
    <componentField>foo</componentField>
  </Example_-Component>
  <Example_-Module>
    <moduleField>bar</moduleField>
  </Example_-Module>
</list>

福
酒吧

您不需要编写任何特殊的构建器,但XML文件的结构与类的实现相同,因此,如果需要任何跨版本的兼容性,那么更改可能会很困难。

我最终向XMLConvertible接口添加了一个抽象生成器,它将在XMLConvertible的所有实现中被覆盖。至少这样,我不必为每个新实现创建2个新文件

public interface XMLConvertible {
    public void write();
    public void read();

    public abstract static class Builder {
        public abstract XMLConvertible build([XML data]);
    }
}

最后,我向XMLConvertible接口添加了一个抽象生成器,它将在XMLConvertible的所有实现中被覆盖。至少这样,我不必为每个新实现创建2个新文件

public interface XMLConvertible {
    public void write();
    public void read();

    public abstract static class Builder {
        public abstract XMLConvertible build([XML data]);
    }
}

这是一个老问题,已经被问过很多次了。但我现在找不到规范的答案。您正在实现序列化。看一看,如果我错了,请纠正我,但就我所见,我仍然需要知道在读取XML时反序列化的是什么类。难道我就不会有同样的问题吗?这是一个老问题,已经被问过很多次了。但我现在找不到规范的答案。您正在实现序列化。看一看,如果我错了,请纠正我,但就我所见,我仍然需要知道在读取XML时反序列化的是什么类。那么,我会不会遇到同样的问题?跨版本兼容性非常重要,但如果我找不到另一个答案,我想这是一个开始。谢谢你的帮助。我还希望自己从头开始编写解决方案,作为我的