Java 如何在使用泛型时修复此未经检查的强制转换错误?
在我的类中,我有一个包含主题节点的列表。这些列表的节点应该从Message类扩展。在节点列表中的方法Java 如何在使用泛型时修复此未经检查的强制转换错误?,java,list,generics,kotlin,Java,List,Generics,Kotlin,在我的类中,我有一个包含主题节点的列表。这些列表的节点应该从Message类扩展。在节点列表中的方法findNode中,搜索具有特定主题的节点,如果该节点匹配,则返回该节点。Java编译器抱怨TopicNode被转换为T类型的TopicNode,因为它可能不是T类型。解决这个问题的最好办法是什么 private val nodes: MutableList<TopicNode<*>> init { this.nodes = ArrayList() } priv
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
}
private val节点:可变列表
初始化{
this.nodes=ArrayList()
}
private fun findNode(主题:字符串):TopicNode?{
用于(节点中的节点){
if(node.topic==topic){
将节点作为TopicNode返回//未选中强制转换:TopicNode到TopicNode
}
}
返回空
}
我想我自己找到了解决方案。您可以使用.filterIsInstance()
来筛选列表中T
类型的项目
这将导致以下解决方案:
private fun <T : Message> findNode(topic: String): TopicNode<T>? {
val messageNodes: List<TopicNode<T>> = nodes.filterIsInstance<TopicNode<T>>()
for (node in messageNodes) {
if (node.topic == topic) {
return node
}
}
return null
}
private fun findNode(主题:String):TopicNode?{
val messageNodes:List=nodes.filterIsInstance()
for(messageNodes中的节点){
if(node.topic==topic){
返回节点
}
}
返回空
}
它检查列表中是否有
TopicNode
类型的项,其中T
从Message
扩展而来。我怀疑这应该是类的参数化,而不是方法的参数化
问题中的代码必须来自未显示的类。该类的每个实例都包含一个节点列表。从方法判断,每个类都包含特定消息类型的节点。但是方法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{
私有val节点:可变列表
初始化{
this.nodes=ArrayList()
}
private fun findNode(主题:字符串):TopicNode{
用于(节点中的节点){
if(node.topic==topic){
返回节点//无需强制转换
}
}
返回空
}
}
这样,该方法已经知道其节点的类型,并且可以直接返回它们
事实上,该类可以简化为:
class MyClass<T : Message> {
private val nodes: MutableList<TopicNode<T>> = ArrayList()
private fun findNode(topic: String)
= nodes.find{ it.topic == topic }
}
class-MyClass{
私有val节点:MutableList=ArrayList()
private fun findNode(主题:字符串)
=节点。查找{it.topic==topic}
}
把它放在那里,以防万一它适合OP的用例,并且他们不需要列表上的“扩展泛型”。有时你看不见森林,只看到树木
private val nodes: MutableList<TopicNode<Message>>
private fun findNode(topic: String) = nodes.firstOrNull{ it.topic == topic}
它对该类有一系列限制。有关该主题的更多信息
我确实觉得评论中的问题很有趣:如何定义列表中的对象应该从另一个类扩展?不确定如果不按照gidds在其回答中所做的路线执行,是否可以执行此操作这些列表的节点应该从消息类扩展。-为什么要使用
呢?也许接下来的问题应该是:如何定义列表中的对象应该从另一个类扩展?
我不知道怎么做@timcastelijn您的代码可以写成:return nodes.filterIsInstance().firstOrNull{it.topic==topic}
inkotlin@Klyner您正在寻找一个特定的元素,但是您事先过滤了整个列表。这将更短:private fun findNode(主题:String)=nodes.firstOrNull{(它作为?TopicNode)?.topic==topic}
,并且只需要一次迭代。但是很明显,如果节点
属于可变列表类型
看起来是一个很好的解决方案,那么原始问题仍然存在。但是将消息
指定为主题节点
的类型是一个好主意吗?是否可以将扩展自Message
的主题节点MyMessage
添加到列表中?
class TopicNode<Out T> {