Invoking a method with a generic type in Kotlin with multiple parameter type constraints

mrpasqal :

I have the following interface method definition written in Java:

<T extends View & ISpecificView> T getSpecificView();

A Java-based consumer code is able to operate on this method simply by invoking it and treat the returned value as an object extending the View class and implementing the ISpecificView interface the following way:

getContainer().getSpecificView().whateverTclassMethod()

Trying to invoke the same code in Kotlin I get the Type inference failed: Not enough information to infer parameter T (...) Please specify it explicitly error on the getSpecificView() method. I'd love to provide the type explicitly, but I'm unable to pass any specific class, since it may be any ancestor of the View class that implements the ISpecificView interface. Passing either single View or ISpecificView does not help - it results in the Type argument is not within its bounds. Expected: View! Found ICustomView and vice versa.

Is there any possibility to pass an equivalent to Java's T extends View & ISpecificView in Kotlin while calling a method, so I can make use of it?

LppEdd :

To recap (and I hope I got the question right!), in Java you can do

final View view = getContainer().getSpecificView();  // or
final ISpecificView iview = getContainer().getSpecificView();

In Kotlin the same thing

val view: View = getContainer().getSpecificView()

results in Type inference failed: Not enough information to infer parameter T


After 50 minutes of trying and trying...
Just create a dummy class (abstract?)

abstract class KView : View(), ISpecificView

And use it to explicitly set a generic return type

val view: View = getContainer().getSpecificView<KView>()
view.whateverClassMethod()

val iview: ISpecificView = getContainer().getSpecificView<KView>()
iview.whateverInterfaceMethod()

// or just

(getContainer().getSpecificView<KView>() as View).whateverClassMethod()
(getContainer().getSpecificView<KView>() as ISpecificView).whateverInterfaceMethod()

A specific cast to View or ISpecificView is required, because if you just do

getContainer().getSpecificView<KView>()

you'll get

class your.package$ExtendingClass cannot be cast to class your.package.KView

but that's is perfectly fine.
Even in Java you need to decide if you want a View or an ISpecificView.


This way you'll be able to operate on all the methods of View or ISpecificView.


Really, I don't know what else to try. Hope someone comes up with something better.

Edit: if what you mean is in Java you do

final ExtendedView ev = getContainer().getSpecificView();

well, this is a bit wrong imho, even if it compiles, as you cannot guarantee the return type is really ExtendedView. You just know for sure it extends View and implements ISpecificView.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=91746&siteId=1