В процессе переписывания Java-кода в Kotlin мне нужно определить тип объекта списка. Дело в том, что неизвестно и может содержать объекты различного типа. Ситуация:
В моем классе Java я определил список с TopicNode
объектами: private List<TopicNode> nodes
. Эти объекты могут содержать сообщения типа T extends Message
. Сообщения могут быть типа Boolean
, Int32
, String
и т. Д. Узел выглядит так:
TopicNode.java
class TopicNode<T extends Message> extends AbstractNodeMain {
// Implementation
}
Javaclass, содержащий этот список, выглядит так:
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
, и он также может варьироваться.
Так как это так, как я могу справиться с этой ситуацией в Котлине? Это вообще возможно?
Заранее большое спасибо!