How to specify @Throws for a property in interface

2019-07-23 21:12发布

问题:

I am currently porting some Java RMI code to Kotlin. The legacy interface in Java is:

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

After running the auto-migration tool, the field bar is changed into a property:

interface Foo: Remote {
    val bar: Bar
}

However, in the migrated program, getBar is no longer marked as throws RemoteException, which causes illegal remote method encountered error in a RMI call.

I was wondering is there any way to mark @Throws for a property?

回答1:

Well, if you look at @Throws:

If there is a specific getter that does not use the backing field, simply annotate it directly:

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

The valid targets for @Throws are

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

So in other cases, you need to target the getter itself and not the property:

@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 specifies that this annotation will be applied to the getter.

Your full interface would be

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

Here's a problem though - in the generated code, there is no throws clause generated. I feel like this may be a bug, as the annotation is clearly marked as targeting these four use-sites. CONSTRUCTOR and FUNCTION definitely work, it's just the property ones that have none generated.


I took a look at the Kotlin compiler trying to find a possible reason, and I found this:

interface ReplStateFacade : Remote {

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

    ...
}

Which interestingly avoids properties in order to use @Throws. Maybe this is a known workaround?



标签: java kotlin rmi