This may be a bit difficult to describe, so I'll try to give a concrete example of what I'm trying to do.
Suppose we have a Facade interface and class (in Java), like this:
interface FacadeInterface<T> {
void method(String from, String via);
}
class Facade<T> implements FacadeInterface<T> {
private Class<T> mClazz;
public Facade(Class<T> clazz) {
mClazz = clazz;
}
@Override
public void method(String from, String via) {
System.out.println("Method called from " + from + " via " + via);
}
}
In my applications, I need to have multiple singletons which hold an instance of the facade. The real facade has additional setup/config parameters but those are irrelevant here.
Before I started using kotlin, I would have a class which holds a static instance of the facade (not really a singleton, but in my case, it served a similar purpose) which proxied the calls to the facade, like this:
public class Singleton {
private static final FacadeInterface<String> sFacade = new Facade<>(String.class);
private Singleton() {
}
public static void method(String from, String via) {
sFacade.method(from, via);
}
}
Now, with Kotlin we have class delegates which allow me to write something like this:
object SingletonKt : FacadeInterface<String> by Facade(String::class.java)
This is great - no more boilerplate and I can call SingletonKt
from Kotlin classes the same way I called the java Singleton
:
Singleton.method("Kotlin", "Singleton")
SingletonKt.method("Kotlin", "SingletonKt")
But, a slight problem arises when I use SingletonKt
from Java. Then I have to specify INSTANCE
:
Singleton.method("Java", "Singleton");
SingletonKt.INSTANCE.method("Java", "SingletonKt");
I am aware of the @JvmStatic
annotation, but the only place I can put it in the SingletonKt
file without causing compile errors is right before FacadeInterface
and it doesn't seem to do the trick.
Is there a way to set up this class delegate so that I can call it from Java as if it were a static method, without introducing the boilerplate of creating proxy methods for SingletonKt
(which would defeat the purpose of the class delegate)?
It's sadly not possilble!
The Kotlin Delegation is a nice way to reduce boilerplate code. But it comes with the inability to actually access the delegate within the class body.
The second issue you're facing regarding @JvmStatic
is actually more drastic to your cause than the first and also applies to you when implementing the delegation manually:
Override members cannot be '@JvmStatic' in object
So instead of exposing the method()
through the INSTANCE
only, you could delegate it to a staticMethod()
on the object. This still differs from your intent, but comes close to it.
object SingletonKt : FacadeInterface<String> by Facade(String::class.java)
@JvmStatic fun staticMethod(from: String, via: String) = method(from, to)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With