2

我正在尝试实现一个表示 XML 树的类,如下所示:

    public class XML<T extends XML<T>> {

        private final List<MarkupLanguage> nodeList = new ArrayList<>();

        private final Map<String, String> attributeList = new HashMap<>();

        public T attr(final String key, final String value) {
            if (value != null) {
                this.attributeList.put(key, value);
            } 
            return (T) this;
        }

        public T appendTo(final T node) {
            node.add(this);
            return (T) this;
        }
        ...
    } 

我的问题是输入这些子句 - 我正在为“return (T) this;”获得未经检查的演员表。

以及当我尝试单独使用 XML 类时:

    final XML url = new XML("url");
    new XML("loc")
        .add("http://goout.cz")
        .appendTo(url);

我正进入(状态:

    Unchecked cast to call appendTo(T) as a member of raw type XML.

如何改进我的代码以获得更好的打字效果?

4

2 回答 2

5

只需输入:

final XML<T> url = new XML<T>("url");
new XML<T>("loc")
    .add("http://goout.cz")
    .appendTo(url);

看起来你真的想使用XML<T>你的方法,而不是T,所以你可以避免强制转换(但我可能是错的):

public XML<T> attr(String key, String value) {
    if (value != null) {
        this.attributeList.put(key, value);
    } 
    return this;
}

public XML<T> appendTo(XML<T> node) {
    node.add(this);
    return this;
}
于 2012-10-13T00:37:59.757 回答
0

下面的方法怎么样(简单继承加上泛型方法):

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class XmlTest {

    @Test
    public void test() {
        XMLFirstSubclass url = new XMLFirstSubclass("url");
        XMLSecondSubclass xmlSecondSubclassInstance = new XMLSecondSubclass(
                "loc").add("http://goout.cz").appendTo(url);
    }
}

abstract class XML {

    private final List<String> texts = new ArrayList<String>();

    private final List<XML> nodes = new ArrayList<XML>();

    private final String nodeName;

    protected XML(String nodeName) {
        this.nodeName = nodeName;
    }

    @SuppressWarnings("unchecked")
    public <R extends XML> R add(String text) {
        texts.add(text);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    public <R extends XML, T extends XML> R add(T node) {
        nodes.add(node);
        return (R) this;
    }

    @SuppressWarnings("unchecked")
    public <R extends XML, T extends XML> R appendTo(T node) {
        node.add(this);
        return (R) this;
    }
}

class XMLFirstSubclass extends XML {
    public XMLFirstSubclass(String nodeName) {
        super(nodeName);
    }
}

class XMLSecondSubclass extends XML {
    public XMLSecondSubclass(String nodeName) {
        super(nodeName);
    }
}

请注意,泛型方法允许从一种类型 T 获取节点并返回实例的类型 R,它可以不同于参数的类型。T 可以不同于 R,但都继承 XML。

关于问题中提出的方法的评论

到目前为止,您使用的方法可能会导致奇怪的情况。让我们用一个例子来说明这一点。

下面,我们尝试编写第一个专门用于 XML 的类:

public class XMLFirstSubclass extends XML<OtherXMLSubclass> { ... }

如果我们正在编写第一个 XML 子类,OtherXMLSubclass 唯一可能的值是 XMLFirstSubclass 或根本不声明泛型类型。

第一个选项:

public class XMLFirstSubclass extends XML<XMLFirstSubclass> { ... }

第二:

public class XMLFirstSubclass extends XML { ... }

如果你选择在你的类设计中使用泛型,第二个选项似乎很糟糕。
仔细研究第一个选项,它打开了获取子类的可能性,例如:

class XMLSecondSubclass extends XML<XMLFirstSubclass> {
    ... 
}

请注意,这可以完美编译,但会在运行时导致 XMLSecondSubclass 方法调用中的类转换异常。

于 2012-10-13T02:01:32.207 回答