我需要解析XML文件并通过反射从ArrayList创建一堆对象。

我通过Class.forName()实现了这一目标。

这是我的代码:

public ArrayList<Sweets> parse(String fileName) throws Exception {

    File file = new File(fileName);
    Document doc = builder.parse(file);

    ArrayList<Sweets> items = new ArrayList<Sweets>();
    int itemCount = Integer.parseInt(path
            .evaluate("count(/gift/item)", doc));

    for (int i = 1; i <= itemCount; i++) {

        double sugar = Double.parseDouble(path.evaluate("/gift/item[" + i + "]/@sugar", doc));
        String name = path.evaluate("/gift/item[" + i + "]/name", doc);
        double weight = Double.parseDouble(path.evaluate("/gift/item[" + i
                + "]/weight", doc));

        Class cl = Class.forName("com.epam.lab.model.chocolate." + name);
        items.add((Sweets) cl.getConstructor(double.class, double.class)
                .newInstance(sugar, weight));
    }

    return items;
}


它有效,但在这一行:

Class cl = Class.forName("com.epam.lab.model.chocolate." + name);


但是缺点是该方法需要具有类include包的全名。

它恰好来自不同的程序包。但是我需要从其他地方选修其他课程。 forName()的限制不允许我这样做。

如何规避Class.forName()约束?

最佳答案

除了将XML读取和解析为Java对象外,还有一个不错的选择:带有注释的JAXB。

阅读方式:

MyDoc doc = load(MyDoc.class, "/mydoc.xml");

private <T> T load(Class<T> klazz, String xmlResource) {
    try {
        JAXBContext jaxbContext = JAXBContext.newInstance(klazz);
        return klazz.cast(jaxbContext.createUnmarshaller()
                .unmarshal(getClass().getResourceAsStream(xmlResource)));
    } catch (JAXBException e) {
        Logger.getLogger(getClass().getName()).log(Level.SEVERE,
                "Cannot read resource " + xmlResource, e);
        throw new IllegalStateException(e);
    }
}

@XmlRootElement(name="document")
public class MyDoc {

    @XmlElement(name="sweetsList")
    public List<Sweets> sweets= new ArrayList<>();
}

<document>
    <sweetsList>
        ...
    </sweetsList>
</document>


对于其他类,使用与@XmlElement@XmlAttribute相同的注释。

关于java - 如何规避Class.forName()方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20636586/

10-10 15:12