如何为接口中的属性指定@Throws

lz9*_*z96 3 java rmi kotlin

我目前正在将一些 Java RMI 代码移植到 Kotlin。Java 中的遗留接口是:

interface Foo: Remote {
    Bar getBar() throws RemoteException
}
Run Code Online (Sandbox Code Playgroud)

运行自动迁移工具后,该字段bar变为属性:

interface Foo: Remote {
    val bar: Bar
}
Run Code Online (Sandbox Code Playgroud)

但是,在迁移后的程序中,getBar不再标记为throws RemoteException,这会导致illegal remote method encounteredRMI 调用出错。

我想知道有什么办法可以标记@Throws房产吗?

Moi*_*ira 5

好吧,如果你看一下@Throws

如果有一个特定的 getter 不使用支持字段,只需直接注释它:

val bar: Bar
    @Throws(RemoteException::class) get() = doSomething()
Run Code Online (Sandbox Code Playgroud)

的有效目标@Throws

AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.CONSTRUCTOR
Run Code Online (Sandbox Code Playgroud)

因此在其他情况下,您需要定位 getter 本身而不是属性:

@get:Throws(RemoteException::class)
Run Code Online (Sandbox Code Playgroud)

支持的使用站点目标的完整列表是:

  • 文件;
  • 属性(具有此目标的注释对 Java 不可见);
  • 场地;
  • get(属性获取器);
  • 设置(属性设置器);
  • 接收者(扩展函数或属性的接收者参数);
  • param(构造函数参数);
  • setparam(属性设置器参数);
  • delegate(存储委托属性的委托实例的字段)。

@get指定此注释将应用于 getter。

你的完整界面是

interface Foo: Remote {
    @get:Throws(RemoteException::class)
    val bar: Bar
}
Run Code Online (Sandbox Code Playgroud)

但这有一个问题 - 在生成的代码中,没有生成子句throws。我觉得这可能是一个错误,因为注释明确标记为针对这四个使用站点。CONSTRUCTOR并且FUNCTION肯定有效,只是没有生成任何财产。


我查看了 Kotlin 编译器,试图找到可能的原因,结果发现

interface ReplStateFacade : Remote {

    @Throws(RemoteException::class)
    fun getId(): Int

    ...
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,为了使用@Throws. 也许这是一个已知的解决方法?