Cloud.orbit.exception.UncheckedException:不知道如何处理状态

时间:2017-07-04 17:55:43

标签: java kotlin

什么是这个java类的kotlin等价物?

public class StatefulActor extends AbstractActor<StatefulActor.State> implements Some
{
    public static class State
    {
        String lastMessage;
    }
}

我试过了:

class HelloActor: AbstractActor<HelloActor.State>(), Hello
{
    inner class State {
        var lastMessage: String? = null
    }

但会产生Cloud.orbit.exception.UncheckedException: Don't know how to handle state

1 个答案:

答案 0 :(得分:2)

  

什么是这个java类的kotlin等价物?

您的Kotlin和Java代码在两个方面有所不同,StateStatefulActor的关系以及State允许子类化的能力。

对于State,您想要的是Nested课程,而不是Kotlin术语中的Inner课程。前者对应于Java中的static修饰符,而后者类似于没有static修饰符的内部类。

因此,为了与您提供的Java代码等效,您应该删除inner关键字。

  

Cloud.orbit.exception.UncheckedException:不知道如何处理状态

关于您的眼睛问题,您可以尝试以下方法。这也将解释为什么子类化是一个问题:

// compile and run with cloud.orbit:orbit-runtime:1.2.0

import cloud.orbit.actors.runtime.AbstractActor
import cloud.orbit.actors.Actor
import cloud.orbit.actors.Stage
import cloud.orbit.concurrent.Task

class HelloActor: AbstractActor<HelloActor.ActorState>(), Hello
{
    override fun sayHello(greeting: String): Task<String> {
        val lastMessage = state().lastMessage
        state().lastMessage = greeting

        return Task.fromValue(lastMessage)
    }

    class ActorState {
        var lastMessage: String? = null
    }
}

interface Hello : Actor {
    fun sayHello(greeting: String): Task<String>
}

fun main(args : Array<String>) {
    val stage = Stage.Builder().clusterName("orbit-helloworld-cluster").build()
    stage.start().join()
    stage.bind()

    val helloActor = Actor.getReference(Hello::class.java, "0");

    var response = helloActor
            .sayHello("Welcome to orbit 1").join()

    println(response) // should print null

    response = helloActor
            .sayHello("Welcome to orbit 2").join()

    println(response) // should print "Welcome to orbit 1"

    stage.stop().join()
}

请注意,在您的问题中,Actor的嵌套类被称为ActorState而不是State。当我命名Actor的状态类State时,我得到了类似的错误:

cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State...
Caused by: cloud.orbit.exception.UncheckedException: cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State
Caused by: cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State
Caused by: cloud.orbit.exception.UncheckedException: java.lang.ClassNotFoundException: HelloActor$ActorState

但是当我使用嵌套的类名HelloActor.ActorState时,它可以工作。

This is because by default all classes in Kotlin are closed (i.e. final in Java terms).

  

默认情况下,Kotlin中的所有类都是final,对应于Effective Java,第17项:设计和继承文档,或者禁止它。

在轨道1.2.0中,code(如果你不使用特殊名称ActorState)尝试继承你的State类,然后实例化它。如果使用闭合的Kotlin默认扩展性,这将不起作用。

如果您希望将自己的名称用于Actor的州级,则必须将其声明为open。 e.g。

class HelloActor: AbstractActor<HelloActor.State>(), Hello
{
    override fun sayHello(greeting: String): Task<String> {
        val lastMessage = state().lastMessage
        state().lastMessage = greeting

        return Task.fromValue(lastMessage)
    }

    open class State {
        var lastMessage: String? = null
    }
}