在我的类里面,我有一个包含TopicNodes的列表。这些列表的节点应从Message类扩展。在节点列表内的findNode方法中,搜索具有特定主题的节点,如果匹配则返回该节点。 Java编译器抱怨TopicNode被转换为T类型的TopicNode,因为它可能不是T类型。解决此问题的最佳方法是什么?

private val nodes: MutableList<TopicNode<*>>

init {
    this.nodes = ArrayList()
}

private fun <T : Message> findNode(topic: String): TopicNode<T>? {
    for (node in nodes) {
        if (node.topic == topic) {
            return node as TopicNode<T> // Unchecked cast: TopicNode<*> to TopicNode<T>
        }
    }
    return null
}

最佳答案

我怀疑这应该参数化类,而不是方法。

问题中的代码必须来自未显示的类。该类的每个实例都包含一个节点列表。从该方法判断,每个类都拥有特定消息类型的节点。但是方法a)要求调用者事先知道哪种类型,而b)允许在同一实例上为不同类型调用它,这毫无意义!

相反,通过在类上提供类型参数而不是方法,可以告诉编译器每个实例都包含特定类型的节点:

class MyClass<T : Message> {
    private val nodes: MutableList<TopicNode<T>>

    init {
        this.nodes = ArrayList()
    }

    private fun findNode(topic: String): TopicNode<T>? {
        for (node in nodes) {
            if (node.topic == topic) {
                return node // No need to cast
            }
        }
        return null
    }
}

这样,该方法已经知道其节点是什么类型,并可以直接返回它们。

实际上,该类可以简化为:
class MyClass<T : Message> {
    private val nodes: MutableList<TopicNode<T>> = ArrayList()

    private fun findNode(topic: String)
        = nodes.find{ it.topic == topic }
}

08-05 11:33