代码之家  ›  专栏  ›  技术社区  ›  lz96

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

  •  3
  • lz96  · 技术社区  · 7 年前

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

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

    运行自动迁移工具后,字段 bar 已更改为属性:

    interface Foo: Remote {
        val bar: Bar
    }
    

    然而,在迁移的程序中, getBar 不再标记为 throws RemoteException ,这导致 illegal remote method encountered RMI调用中出错。

    我想知道有没有办法 @Throws 为了一个财产?

    1 回复  |  直到 7 年前
        1
  •  5
  •   Salem    7 年前

    如果你看 @Throws :

    如果有一个特定的getter不使用backing字段,只需直接对其进行注释:

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

    的有效目标 @投掷

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

    因此,在其他情况下,您需要以getter本身而不是属性为目标:

    @get:Throws(RemoteException::class)
    

    The full list of supported use-site targets 是:

    • 文件
    • 属性(具有此目标的注释对Java不可见);
    • 领域
    • get(属性getter);
    • set(属性设置器);
    • receiver(扩展函数或属性的receiver参数);
    • param(构造函数参数);
    • setparam(属性设置器参数);
    • 委托(存储委托属性的委托实例的字段)。

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

    您的完整界面将是

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

    但有一个问题-在生成的代码中 throws 生成的子句。我觉得这可能是一个bug,因为注释明确标记为针对这四个使用站点。 CONSTRUCTOR FUNCTION 当然有效,只是没有生成的属性。


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

    interface ReplStateFacade : Remote {
    
        @Throws(RemoteException::class)
        fun getId(): Int
    
        ...
    }
    

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