java - 如何处理从 Java 到 Kotlin 的通用列表转换?
问题描述
在将 Java 代码重写为 Kotlin 的过程中,我需要定义一个列表的对象类型。问题是它是未知的,它可以包含不同类型的对象。情况:
在我的 Java 类中,我定义了一个包含TopicNode
对象的列表:private List<TopicNode> nodes
. 这些对象可以包含一个类型的消息T extends Message
。消息可以是 , 等类型Boolean
。Int32
一个String
节点看起来像:
主题节点.java
class TopicNode<T extends Message> extends AbstractNodeMain {
// Implementation
}
包含此列表的 Java 类如下所示:
TopicControllerImpl.java
public class TopicControllerImpl implements TopicController {
private List<TopicNode> nodes;
@Override
public void subscribe(String topic, Class type, Messenger subscriber) {
TopicNode node = findOrCreateNode(topic, type);
node.addListener(subscriber);
}
private <T extends Message> TopicNode<T> findNode(String topic) {
for (TopicNode node : nodes) {
if (node.getTopic().equals(topic)) {
return (TopicNode<T>) node;
}
}
return null;
}
private <T extends Message> TopicNode findOrCreateNode(String topic, Class<T> type) {
TopicNode<T> node = findNode(topic);
if (node != null) {
return node;
}
// If node doesn't exist yet, create it, run it and add it to the collection
node = new TopicNode<>(topic, type);
executor.execute(node, configuration);
nodes.add(node);
return node;
}
}
当我尝试在 Kotlin ( private val nodes: ArrayList<TopicNode> = ArrayList()
) 中定义这样的列表时,编译器会说:One type argument expected for class TopicNode<T : Message>
.
为了解决这个问题,您可以在 Kotlin 中定义如下所示的类和列表:
TopicControllerImpl.kt
class TopicControllerImpl<T : Message>(/** args */) : TopicController<T> {
private val nodes: ArrayList<TopicNode<T>> = ArrayList()
override fun subscribe(topic: String, type: Class<T>, subscriber: Messenger) {
val node = findOrCreateNode(topic, type)
node.addListener(subscriber)
}
private fun findNode(topic: String): TopicNode<T>? {
return nodes.firstOrNull { it.topic == topic }
}
private fun findOrCreateNode(topic: String, type: Class<T>): TopicNode<T>
{
var node = findNode(topic)
if (node != null) {
return node
}
// If node doesn't exist yet, create it, run it and add it to the collection
node = TopicNode(topic, type)
executor.execute(node, configuration)
nodes.add(node)
return node
}
}
这样做的问题是您需要定义T
用于列表的类型,TopicControllerImpl
而这个未知并且在 Java 中不需要。未知的类型将Message
是什么,它也可能会有所不同。
既然是这种情况,我该如何处理 Kotlin 中的这种情况?甚至可能吗?
提前非常感谢!
解决方案
这是泛型和通配符之间的区别。例如
private val nodes: ArrayList<TopicNode<T>> = ArrayList()
意味着我将拥有一个具有给定类型的泛型类的数组T
。尽管
private val nodes: ArrayList<TopicNode<*>> = ArrayList()
意味着我将拥有一个混合类型的泛型类的数组。
如果您想使用第一个更改您的类定义,但如果您想使用第二个更改您的数组声明。
推荐阅读
- c++ - C++ 中是否有用于在字符串中选取数字的函数
- python - 如何将第一个处理过的图像(例如 Canny 过滤器)的输出作为另一个处理过滤器的输入?
- docx - 从word中提取文本并转换为Dataframe
- python - win32com EnsureDispatch 在创建 gen_py 缓存时无法加载 DLL
- matlab - 如何生成不同 dB 的 BER 性能?
- c# - C# itextsharp - 创建 PDF,在文件夹中创建文件夹,将 PDF 放在最深的文件夹中
- python - 如何使用 pandas/python 找到不重叠的持续时间
- bash - 我可以将 terraform 输出设置为 env 变量吗?
- python - 当 C 函数返回 NULL 时,Python ctypes 函数返回 ValueError
- r - 在 dplyr::group_modify 中使用 purrr::possibly() 生成整洁的模型统计信息