如何在界面中为 属性 指定 @Throws

How to specify @Throws for a property in interface

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

interface Foo: Remote {
    Bar getBar() throws RemoteException
}

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

interface Foo: Remote {
    val bar: Bar
}

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

我想知道有什么方法可以将 @Throws 标记为 属性?

好吧,如果你看看 @Throws:

如果有特定的getter不使用backing field,直接注释即可:

val bar: Bar
    @Throws(RemoteException::class) get() = doSomething()

@Throws 的有效目标是

AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.CONSTRUCTOR

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

@get:Throws(RemoteException::class)

The full list of supported use-site targets is:

  • file;
  • property (annotations with this target are not visible to Java);
  • field;
  • get (property getter);
  • set (property setter);
  • receiver (receiver parameter of an extension function or property);
  • param (constructor parameter);
  • setparam (property setter parameter);
  • delegate (the field storing the delegate instance for a delegated property).

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

您的完整界面将是

interface Foo: Remote {
    @get:Throws(RemoteException::class)
    val bar: Bar
}

这里有一个问题 - 在生成的代码中, 没有生成 throws 子句。我觉得这可能是一个错误,因为注释清楚地标记为针对这四个使用站点。 CONSTRUCTORFUNCTION 绝对有效,只是 属性 生成了 none。


我查看了 Kotlin 编译器试图找出可能的原因,我发现 this:

interface ReplStateFacade : Remote {

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

    ...
}

有趣的是为了使用 @Throws 而避免了属性。 也许这是一个已知的解决方法?