In kotlin, what is the proper way to test if a value of a generic type implements an interface, and then use it as that interface?Java generics type erasure: when and what happens?How to get actual type arguments of a reified generic parameter in Kotlin?How do I address unchecked cast warnings?Can generic types be used as the “type” of a composite component's attribute tag?How is a type-erased generic wrapper implemented?Generic extending class AND implements interface in KotlinGenerics on KProperty1.getDelegate too restrictive?Kotlin: gettng rid of Unchecked casts for ComparableKotlin: Generic function as return type?Base Presenter Test class using Mockito and Kotlin - working around Generic type erasureReified inline function for arraysKotlin force nullable generic type into a non-nullable of the same generic type?

I found a password with hashcat, but it doesn't work

King or Queen-Which piece is which?

How to maintain a closed environment for one person for a long period of time

Why does independence imply zero correlation?

Prime sieve in Python

Designing a magic-compatible polearm

Counterfeit checks were created for my account. How does this type of fraud work?

Is there any difference between Т34ВМ1 and КМ1858ВМ1/3?

Shooting someone's past self using special relativity

Boss wants someone else to lead a project based on the idea I presented to him

How many people are necessary to maintain modern civilisation?

Music theory behind A chord in the key of G

Can I enter the UK for 24 hours from a Schengen area, holding an Indian passport?

Intuition for the role of diffeomorphisms

How do I choose a villain in the Waterdeep: Dragon Heist adventure?

Understanding the reasoning of the woman who agreed with Shlomo to "cut the baby in half"

How can lift be less than thrust that is less than weight?

Should I include an appendix for inessential, yet related worldbuilding to my story?

How to make clear to people I don't want to answer their "Where are you from?" question?

How do I professionally let my manager know I'll quit over an issue?

I don't like coffee, neither beer. How to politely work my way around that in a business situation?

Is it possible to get a mortgage with a custom duration in the US?

Why is "Congress shall have power to enforce this article by appropriate legislation" necessary?

What is the highest voltage from the power supply a Raspberry Pi 3 B can handle without getting damaged?



In kotlin, what is the proper way to test if a value of a generic type implements an interface, and then use it as that interface?


Java generics type erasure: when and what happens?How to get actual type arguments of a reified generic parameter in Kotlin?How do I address unchecked cast warnings?Can generic types be used as the “type” of a composite component's attribute tag?How is a type-erased generic wrapper implemented?Generic extending class AND implements interface in KotlinGenerics on KProperty1.getDelegate too restrictive?Kotlin: gettng rid of Unchecked casts for ComparableKotlin: Generic function as return type?Base Presenter Test class using Mockito and Kotlin - working around Generic type erasureReified inline function for arraysKotlin force nullable generic type into a non-nullable of the same generic type?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















Given a method which accepts a parameter of a generic type, I would like to check if the type implements Comparable, and if so, compare it with another value.



Assuming the type parameter is T, since T is erased, a test of the form t is Comparable<T> is not possible, even with reified type parameters. A test of the form t is Comparable<*> is possible and works, but then t cannot be used as Comparable, because Comparable<*> is out-projected.



fun <T> examine(a: T, b: T) 
if (a is Comparable<*>)
a <= b




This fails with:



Kotlin: Out-projected type 'Comparable<*>' prohibits the use of 'public abstract operator fun compareTo(other: T): Int defined in kotlin.Comparable'



The one workaround that I can see is



fun <T> examine(a: T, b: T) 
if (a is Comparable<*>)
println(a as Comparable<T> <= b)




which has the unchecked cast, but why is this cast necessary?



Should smart casting not take care of this because of the test we do to check if a is comparable? Are the different type parameters not allowing the smart cast to happen here?



Is this the recommended way to test for Comparable or is there another solution which could avoid unchecked casts?










share|improve this question




























    1















    Given a method which accepts a parameter of a generic type, I would like to check if the type implements Comparable, and if so, compare it with another value.



    Assuming the type parameter is T, since T is erased, a test of the form t is Comparable<T> is not possible, even with reified type parameters. A test of the form t is Comparable<*> is possible and works, but then t cannot be used as Comparable, because Comparable<*> is out-projected.



    fun <T> examine(a: T, b: T) 
    if (a is Comparable<*>)
    a <= b




    This fails with:



    Kotlin: Out-projected type 'Comparable<*>' prohibits the use of 'public abstract operator fun compareTo(other: T): Int defined in kotlin.Comparable'



    The one workaround that I can see is



    fun <T> examine(a: T, b: T) 
    if (a is Comparable<*>)
    println(a as Comparable<T> <= b)




    which has the unchecked cast, but why is this cast necessary?



    Should smart casting not take care of this because of the test we do to check if a is comparable? Are the different type parameters not allowing the smart cast to happen here?



    Is this the recommended way to test for Comparable or is there another solution which could avoid unchecked casts?










    share|improve this question
























      1












      1








      1


      1






      Given a method which accepts a parameter of a generic type, I would like to check if the type implements Comparable, and if so, compare it with another value.



      Assuming the type parameter is T, since T is erased, a test of the form t is Comparable<T> is not possible, even with reified type parameters. A test of the form t is Comparable<*> is possible and works, but then t cannot be used as Comparable, because Comparable<*> is out-projected.



      fun <T> examine(a: T, b: T) 
      if (a is Comparable<*>)
      a <= b




      This fails with:



      Kotlin: Out-projected type 'Comparable<*>' prohibits the use of 'public abstract operator fun compareTo(other: T): Int defined in kotlin.Comparable'



      The one workaround that I can see is



      fun <T> examine(a: T, b: T) 
      if (a is Comparable<*>)
      println(a as Comparable<T> <= b)




      which has the unchecked cast, but why is this cast necessary?



      Should smart casting not take care of this because of the test we do to check if a is comparable? Are the different type parameters not allowing the smart cast to happen here?



      Is this the recommended way to test for Comparable or is there another solution which could avoid unchecked casts?










      share|improve this question














      Given a method which accepts a parameter of a generic type, I would like to check if the type implements Comparable, and if so, compare it with another value.



      Assuming the type parameter is T, since T is erased, a test of the form t is Comparable<T> is not possible, even with reified type parameters. A test of the form t is Comparable<*> is possible and works, but then t cannot be used as Comparable, because Comparable<*> is out-projected.



      fun <T> examine(a: T, b: T) 
      if (a is Comparable<*>)
      a <= b




      This fails with:



      Kotlin: Out-projected type 'Comparable<*>' prohibits the use of 'public abstract operator fun compareTo(other: T): Int defined in kotlin.Comparable'



      The one workaround that I can see is



      fun <T> examine(a: T, b: T) 
      if (a is Comparable<*>)
      println(a as Comparable<T> <= b)




      which has the unchecked cast, but why is this cast necessary?



      Should smart casting not take care of this because of the test we do to check if a is comparable? Are the different type parameters not allowing the smart cast to happen here?



      Is this the recommended way to test for Comparable or is there another solution which could avoid unchecked casts?







      generics kotlin






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 25 at 7:35









      abhijatabhijat

      5236




      5236






















          2 Answers
          2






          active

          oldest

          votes


















          3














          The cast in your example is obviously necessary because you only ensure that a is a Comparable of an unknown type (star projected). And this cast can even fail. Think about a class A: Comparable<B>. You would cast it to Comparable<A> although it can only be compared to B.



          You can also think about providing two functions, one restricted to T: Comparable<T> using an upper bound and one for non-comparable types. In this case, you would not need to cast anything.






          share|improve this answer























          • stackoverflow.com/questions/36253310/… might also be helpful

            – s1m0nw1
            Mar 25 at 8:46


















          1














          You can't.



          This is an unfortunate consequence of type erasure. When generics were first added to Java, for backward compatibility it was done only at compile-time; the compiled code has no knowledge of type parameters or their restrictions. So at run-time there's no such thing as a Compatable<T>, just Comparable. That's why the type parameter can't be checked with is.



          Kotlin has a workaround in some circumstances; if the function is inline, you can mark a type parameter as reified, and it can then use the type parameter in the inlined code. But that's not a solution here, as it can only provide the type T, not the parameterised type of Comparable if a implements it.






          share|improve this answer

























          • Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

            – abhijat
            Mar 25 at 8:40






          • 1





            Thanks, @abhijat, I'll update the answer.

            – gidds
            Mar 25 at 8:55











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55333089%2fin-kotlin-what-is-the-proper-way-to-test-if-a-value-of-a-generic-type-implement%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          The cast in your example is obviously necessary because you only ensure that a is a Comparable of an unknown type (star projected). And this cast can even fail. Think about a class A: Comparable<B>. You would cast it to Comparable<A> although it can only be compared to B.



          You can also think about providing two functions, one restricted to T: Comparable<T> using an upper bound and one for non-comparable types. In this case, you would not need to cast anything.






          share|improve this answer























          • stackoverflow.com/questions/36253310/… might also be helpful

            – s1m0nw1
            Mar 25 at 8:46















          3














          The cast in your example is obviously necessary because you only ensure that a is a Comparable of an unknown type (star projected). And this cast can even fail. Think about a class A: Comparable<B>. You would cast it to Comparable<A> although it can only be compared to B.



          You can also think about providing two functions, one restricted to T: Comparable<T> using an upper bound and one for non-comparable types. In this case, you would not need to cast anything.






          share|improve this answer























          • stackoverflow.com/questions/36253310/… might also be helpful

            – s1m0nw1
            Mar 25 at 8:46













          3












          3








          3







          The cast in your example is obviously necessary because you only ensure that a is a Comparable of an unknown type (star projected). And this cast can even fail. Think about a class A: Comparable<B>. You would cast it to Comparable<A> although it can only be compared to B.



          You can also think about providing two functions, one restricted to T: Comparable<T> using an upper bound and one for non-comparable types. In this case, you would not need to cast anything.






          share|improve this answer













          The cast in your example is obviously necessary because you only ensure that a is a Comparable of an unknown type (star projected). And this cast can even fail. Think about a class A: Comparable<B>. You would cast it to Comparable<A> although it can only be compared to B.



          You can also think about providing two functions, one restricted to T: Comparable<T> using an upper bound and one for non-comparable types. In this case, you would not need to cast anything.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 25 at 8:03









          s1m0nw1s1m0nw1

          32.9k659116




          32.9k659116












          • stackoverflow.com/questions/36253310/… might also be helpful

            – s1m0nw1
            Mar 25 at 8:46

















          • stackoverflow.com/questions/36253310/… might also be helpful

            – s1m0nw1
            Mar 25 at 8:46
















          stackoverflow.com/questions/36253310/… might also be helpful

          – s1m0nw1
          Mar 25 at 8:46





          stackoverflow.com/questions/36253310/… might also be helpful

          – s1m0nw1
          Mar 25 at 8:46













          1














          You can't.



          This is an unfortunate consequence of type erasure. When generics were first added to Java, for backward compatibility it was done only at compile-time; the compiled code has no knowledge of type parameters or their restrictions. So at run-time there's no such thing as a Compatable<T>, just Comparable. That's why the type parameter can't be checked with is.



          Kotlin has a workaround in some circumstances; if the function is inline, you can mark a type parameter as reified, and it can then use the type parameter in the inlined code. But that's not a solution here, as it can only provide the type T, not the parameterised type of Comparable if a implements it.






          share|improve this answer

























          • Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

            – abhijat
            Mar 25 at 8:40






          • 1





            Thanks, @abhijat, I'll update the answer.

            – gidds
            Mar 25 at 8:55















          1














          You can't.



          This is an unfortunate consequence of type erasure. When generics were first added to Java, for backward compatibility it was done only at compile-time; the compiled code has no knowledge of type parameters or their restrictions. So at run-time there's no such thing as a Compatable<T>, just Comparable. That's why the type parameter can't be checked with is.



          Kotlin has a workaround in some circumstances; if the function is inline, you can mark a type parameter as reified, and it can then use the type parameter in the inlined code. But that's not a solution here, as it can only provide the type T, not the parameterised type of Comparable if a implements it.






          share|improve this answer

























          • Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

            – abhijat
            Mar 25 at 8:40






          • 1





            Thanks, @abhijat, I'll update the answer.

            – gidds
            Mar 25 at 8:55













          1












          1








          1







          You can't.



          This is an unfortunate consequence of type erasure. When generics were first added to Java, for backward compatibility it was done only at compile-time; the compiled code has no knowledge of type parameters or their restrictions. So at run-time there's no such thing as a Compatable<T>, just Comparable. That's why the type parameter can't be checked with is.



          Kotlin has a workaround in some circumstances; if the function is inline, you can mark a type parameter as reified, and it can then use the type parameter in the inlined code. But that's not a solution here, as it can only provide the type T, not the parameterised type of Comparable if a implements it.






          share|improve this answer















          You can't.



          This is an unfortunate consequence of type erasure. When generics were first added to Java, for backward compatibility it was done only at compile-time; the compiled code has no knowledge of type parameters or their restrictions. So at run-time there's no such thing as a Compatable<T>, just Comparable. That's why the type parameter can't be checked with is.



          Kotlin has a workaround in some circumstances; if the function is inline, you can mark a type parameter as reified, and it can then use the type parameter in the inlined code. But that's not a solution here, as it can only provide the type T, not the parameterised type of Comparable if a implements it.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 25 at 9:00

























          answered Mar 25 at 8:05









          giddsgidds

          2,128138




          2,128138












          • Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

            – abhijat
            Mar 25 at 8:40






          • 1





            Thanks, @abhijat, I'll update the answer.

            – gidds
            Mar 25 at 8:55

















          • Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

            – abhijat
            Mar 25 at 8:40






          • 1





            Thanks, @abhijat, I'll update the answer.

            – gidds
            Mar 25 at 8:55
















          Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

          – abhijat
          Mar 25 at 8:40





          Unfortunately, even with reified parameters while T is now visible to the inlined function, it appears that something like Comparable<T> is still erased.

          – abhijat
          Mar 25 at 8:40




          1




          1





          Thanks, @abhijat, I'll update the answer.

          – gidds
          Mar 25 at 8:55





          Thanks, @abhijat, I'll update the answer.

          – gidds
          Mar 25 at 8:55

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55333089%2fin-kotlin-what-is-the-proper-way-to-test-if-a-value-of-a-generic-type-implement%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

          Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

          Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript