Java 8 cannot be applied to interface












7















Using Optional, I want to return a certain implementation (First or Second) of an interface according to the mapping result. This is the interface that First and Second implement:



public interface MyInterface {
Number number();
}


The following Optional usage is erroneous:



final String string = ...                          // might be null
final Number number = Optional.ofNullable(string)
.map(string -> new First())
.orElse(new Second()) // erroneous line
.number();



orElse (com.mycompany.First) in Optional cannot be applied to (com.mycompany.Second)




Why is the line erroneous since both of the classes First and Second implement the interface MyInterface and the method MyInterface::number returns Number? How to implement this correctly?










share|improve this question





























    7















    Using Optional, I want to return a certain implementation (First or Second) of an interface according to the mapping result. This is the interface that First and Second implement:



    public interface MyInterface {
    Number number();
    }


    The following Optional usage is erroneous:



    final String string = ...                          // might be null
    final Number number = Optional.ofNullable(string)
    .map(string -> new First())
    .orElse(new Second()) // erroneous line
    .number();



    orElse (com.mycompany.First) in Optional cannot be applied to (com.mycompany.Second)




    Why is the line erroneous since both of the classes First and Second implement the interface MyInterface and the method MyInterface::number returns Number? How to implement this correctly?










    share|improve this question



























      7












      7








      7


      1






      Using Optional, I want to return a certain implementation (First or Second) of an interface according to the mapping result. This is the interface that First and Second implement:



      public interface MyInterface {
      Number number();
      }


      The following Optional usage is erroneous:



      final String string = ...                          // might be null
      final Number number = Optional.ofNullable(string)
      .map(string -> new First())
      .orElse(new Second()) // erroneous line
      .number();



      orElse (com.mycompany.First) in Optional cannot be applied to (com.mycompany.Second)




      Why is the line erroneous since both of the classes First and Second implement the interface MyInterface and the method MyInterface::number returns Number? How to implement this correctly?










      share|improve this question
















      Using Optional, I want to return a certain implementation (First or Second) of an interface according to the mapping result. This is the interface that First and Second implement:



      public interface MyInterface {
      Number number();
      }


      The following Optional usage is erroneous:



      final String string = ...                          // might be null
      final Number number = Optional.ofNullable(string)
      .map(string -> new First())
      .orElse(new Second()) // erroneous line
      .number();



      orElse (com.mycompany.First) in Optional cannot be applied to (com.mycompany.Second)




      Why is the line erroneous since both of the classes First and Second implement the interface MyInterface and the method MyInterface::number returns Number? How to implement this correctly?







      java generics java-8 interface optional






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 5 hours ago







      Nikolas

















      asked 5 hours ago









      NikolasNikolas

      13.2k53367




      13.2k53367
























          4 Answers
          4






          active

          oldest

          votes


















          3














          The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:



          private static void main(String... args)
          {
          final String string = "";
          final Number number = Optional.ofNullable(string)
          .<MyInterface>map(str -> new First()) // Explicit type specified
          .orElse(new Second())
          .number();
          }


          This is a generic limitation of type inference along method chains. It's not limited to Optional.



          There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?



          Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.






          share|improve this answer


























          • Java *infers* the mapped type to be First - that's a right formulation.

            – Nikolas
            5 hours ago











          • @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

            – Michael
            5 hours ago











          • @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

            – Eugene
            20 mins ago



















          3














          I have discovered out that the method Optional::map returns U which doesn't allow apply returned First to another type such Second is. An explicit casting to its interface or requiring it within the map method is a way to go:



          final Number number = Optional.ofNullable("")
          .<MyInterface>map(string -> new First())
          .orElse(new Second())
          .number();


          __



          Edit: I have found this out after posting the question. However, I am keeping both since I haven't found a similar solution anywhere else yet.






          share|improve this answer





















          • 3





            I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

            – marstran
            5 hours ago













          • @marstran: Agreed, thanks for the hint :)

            – Nikolas
            5 hours ago






          • 2





            @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

            – glglgl
            5 hours ago











          • @glglgl: I mean I could put a bit more effort to find the solution :))

            – Nikolas
            5 hours ago



















          1














          I would write that without an explicit cast:



          Optional.ofNullable(string)
          .map(s -> {
          MyInterface m = new First();
          return m;
          })
          .orElse(new Second())
          .number();





          share|improve this answer





















          • 1





            Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

            – Nikolas
            5 hours ago






          • 1





            I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

            – BackSlash
            5 hours ago



















          0














          Well as the explanation stands true in other answers as well, its the type inferred while using the map that errors out the orElse in use, a cleaner way to represent the suggested solution would be :



          Optional.ofNullable(string)
          .map(s -> (MyInterface) new First()) // casting rather than binding here
          .orElse(new Second())
          .number();





          share|improve this answer
























          • Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

            – nullpointer
            3 hours ago











          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%2f54238488%2fjava-8-cannot-be-applied-to-interface%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:



          private static void main(String... args)
          {
          final String string = "";
          final Number number = Optional.ofNullable(string)
          .<MyInterface>map(str -> new First()) // Explicit type specified
          .orElse(new Second())
          .number();
          }


          This is a generic limitation of type inference along method chains. It's not limited to Optional.



          There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?



          Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.






          share|improve this answer


























          • Java *infers* the mapped type to be First - that's a right formulation.

            – Nikolas
            5 hours ago











          • @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

            – Michael
            5 hours ago











          • @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

            – Eugene
            20 mins ago
















          3














          The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:



          private static void main(String... args)
          {
          final String string = "";
          final Number number = Optional.ofNullable(string)
          .<MyInterface>map(str -> new First()) // Explicit type specified
          .orElse(new Second())
          .number();
          }


          This is a generic limitation of type inference along method chains. It's not limited to Optional.



          There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?



          Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.






          share|improve this answer


























          • Java *infers* the mapped type to be First - that's a right formulation.

            – Nikolas
            5 hours ago











          • @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

            – Michael
            5 hours ago











          • @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

            – Eugene
            20 mins ago














          3












          3








          3







          The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:



          private static void main(String... args)
          {
          final String string = "";
          final Number number = Optional.ofNullable(string)
          .<MyInterface>map(str -> new First()) // Explicit type specified
          .orElse(new Second())
          .number();
          }


          This is a generic limitation of type inference along method chains. It's not limited to Optional.



          There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?



          Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.






          share|improve this answer















          The problem is that Java infers the mapped type to be First, and Second is not an instance of First. You need to explicitly give Java a bit of a nudge to know the right type:



          private static void main(String... args)
          {
          final String string = "";
          final Number number = Optional.ofNullable(string)
          .<MyInterface>map(str -> new First()) // Explicit type specified
          .orElse(new Second())
          .number();
          }


          This is a generic limitation of type inference along method chains. It's not limited to Optional.



          There has been some suggestion to have type inference work along method chains. See this question: Generic type inference not working with method chaining?



          Maybe in a future version of Java the compiler will be clever enough to figure this out. Who knows.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 5 hours ago

























          answered 5 hours ago









          MichaelMichael

          19.1k73369




          19.1k73369













          • Java *infers* the mapped type to be First - that's a right formulation.

            – Nikolas
            5 hours ago











          • @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

            – Michael
            5 hours ago











          • @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

            – Eugene
            20 mins ago



















          • Java *infers* the mapped type to be First - that's a right formulation.

            – Nikolas
            5 hours ago











          • @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

            – Michael
            5 hours ago











          • @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

            – Eugene
            20 mins ago

















          Java *infers* the mapped type to be First - that's a right formulation.

          – Nikolas
          5 hours ago





          Java *infers* the mapped type to be First - that's a right formulation.

          – Nikolas
          5 hours ago













          @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

          – Michael
          5 hours ago





          @Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.

          – Michael
          5 hours ago













          @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

          – Eugene
          20 mins ago





          @Michael I don't think that would be possible, AFAIK, inference works on per method basis - first infer one, then the next and so on; what you are implying must work for all chained methods at once - I doubt that would be ever possible.

          – Eugene
          20 mins ago













          3














          I have discovered out that the method Optional::map returns U which doesn't allow apply returned First to another type such Second is. An explicit casting to its interface or requiring it within the map method is a way to go:



          final Number number = Optional.ofNullable("")
          .<MyInterface>map(string -> new First())
          .orElse(new Second())
          .number();


          __



          Edit: I have found this out after posting the question. However, I am keeping both since I haven't found a similar solution anywhere else yet.






          share|improve this answer





















          • 3





            I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

            – marstran
            5 hours ago













          • @marstran: Agreed, thanks for the hint :)

            – Nikolas
            5 hours ago






          • 2





            @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

            – glglgl
            5 hours ago











          • @glglgl: I mean I could put a bit more effort to find the solution :))

            – Nikolas
            5 hours ago
















          3














          I have discovered out that the method Optional::map returns U which doesn't allow apply returned First to another type such Second is. An explicit casting to its interface or requiring it within the map method is a way to go:



          final Number number = Optional.ofNullable("")
          .<MyInterface>map(string -> new First())
          .orElse(new Second())
          .number();


          __



          Edit: I have found this out after posting the question. However, I am keeping both since I haven't found a similar solution anywhere else yet.






          share|improve this answer





















          • 3





            I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

            – marstran
            5 hours ago













          • @marstran: Agreed, thanks for the hint :)

            – Nikolas
            5 hours ago






          • 2





            @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

            – glglgl
            5 hours ago











          • @glglgl: I mean I could put a bit more effort to find the solution :))

            – Nikolas
            5 hours ago














          3












          3








          3







          I have discovered out that the method Optional::map returns U which doesn't allow apply returned First to another type such Second is. An explicit casting to its interface or requiring it within the map method is a way to go:



          final Number number = Optional.ofNullable("")
          .<MyInterface>map(string -> new First())
          .orElse(new Second())
          .number();


          __



          Edit: I have found this out after posting the question. However, I am keeping both since I haven't found a similar solution anywhere else yet.






          share|improve this answer















          I have discovered out that the method Optional::map returns U which doesn't allow apply returned First to another type such Second is. An explicit casting to its interface or requiring it within the map method is a way to go:



          final Number number = Optional.ofNullable("")
          .<MyInterface>map(string -> new First())
          .orElse(new Second())
          .number();


          __



          Edit: I have found this out after posting the question. However, I am keeping both since I haven't found a similar solution anywhere else yet.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 3 hours ago









          nullpointer

          45.6k1097186




          45.6k1097186










          answered 5 hours ago









          NikolasNikolas

          13.2k53367




          13.2k53367








          • 3





            I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

            – marstran
            5 hours ago













          • @marstran: Agreed, thanks for the hint :)

            – Nikolas
            5 hours ago






          • 2





            @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

            – glglgl
            5 hours ago











          • @glglgl: I mean I could put a bit more effort to find the solution :))

            – Nikolas
            5 hours ago














          • 3





            I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

            – marstran
            5 hours ago













          • @marstran: Agreed, thanks for the hint :)

            – Nikolas
            5 hours ago






          • 2





            @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

            – glglgl
            5 hours ago











          • @glglgl: I mean I could put a bit more effort to find the solution :))

            – Nikolas
            5 hours ago








          3




          3





          I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

          – marstran
          5 hours ago







          I would say specifying the type parameter explicitly, is better than casting. Something like this: .<MyInterface>map(string -> new First())

          – marstran
          5 hours ago















          @marstran: Agreed, thanks for the hint :)

          – Nikolas
          5 hours ago





          @marstran: Agreed, thanks for the hint :)

          – Nikolas
          5 hours ago




          2




          2





          @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

          – glglgl
          5 hours ago





          @Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.

          – glglgl
          5 hours ago













          @glglgl: I mean I could put a bit more effort to find the solution :))

          – Nikolas
          5 hours ago





          @glglgl: I mean I could put a bit more effort to find the solution :))

          – Nikolas
          5 hours ago











          1














          I would write that without an explicit cast:



          Optional.ofNullable(string)
          .map(s -> {
          MyInterface m = new First();
          return m;
          })
          .orElse(new Second())
          .number();





          share|improve this answer





















          • 1





            Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

            – Nikolas
            5 hours ago






          • 1





            I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

            – BackSlash
            5 hours ago
















          1














          I would write that without an explicit cast:



          Optional.ofNullable(string)
          .map(s -> {
          MyInterface m = new First();
          return m;
          })
          .orElse(new Second())
          .number();





          share|improve this answer





















          • 1





            Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

            – Nikolas
            5 hours ago






          • 1





            I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

            – BackSlash
            5 hours ago














          1












          1








          1







          I would write that without an explicit cast:



          Optional.ofNullable(string)
          .map(s -> {
          MyInterface m = new First();
          return m;
          })
          .orElse(new Second())
          .number();





          share|improve this answer















          I would write that without an explicit cast:



          Optional.ofNullable(string)
          .map(s -> {
          MyInterface m = new First();
          return m;
          })
          .orElse(new Second())
          .number();






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 5 hours ago

























          answered 5 hours ago









          EugeneEugene

          69k999164




          69k999164








          • 1





            Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

            – Nikolas
            5 hours ago






          • 1





            I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

            – BackSlash
            5 hours ago














          • 1





            Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

            – Nikolas
            5 hours ago






          • 1





            I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

            – BackSlash
            5 hours ago








          1




          1





          Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

          – Nikolas
          5 hours ago





          Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.

          – Nikolas
          5 hours ago




          1




          1





          I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

          – BackSlash
          5 hours ago





          I would write that without a cast - Writing without a cast doesn't mean it won't happen, in this case you'll have an implicit upcast. An explicit cast makes the lambda shorter (but it's still better to specify the type in the map call)

          – BackSlash
          5 hours ago











          0














          Well as the explanation stands true in other answers as well, its the type inferred while using the map that errors out the orElse in use, a cleaner way to represent the suggested solution would be :



          Optional.ofNullable(string)
          .map(s -> (MyInterface) new First()) // casting rather than binding here
          .orElse(new Second())
          .number();





          share|improve this answer
























          • Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

            – nullpointer
            3 hours ago
















          0














          Well as the explanation stands true in other answers as well, its the type inferred while using the map that errors out the orElse in use, a cleaner way to represent the suggested solution would be :



          Optional.ofNullable(string)
          .map(s -> (MyInterface) new First()) // casting rather than binding here
          .orElse(new Second())
          .number();





          share|improve this answer
























          • Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

            – nullpointer
            3 hours ago














          0












          0








          0







          Well as the explanation stands true in other answers as well, its the type inferred while using the map that errors out the orElse in use, a cleaner way to represent the suggested solution would be :



          Optional.ofNullable(string)
          .map(s -> (MyInterface) new First()) // casting rather than binding here
          .orElse(new Second())
          .number();





          share|improve this answer













          Well as the explanation stands true in other answers as well, its the type inferred while using the map that errors out the orElse in use, a cleaner way to represent the suggested solution would be :



          Optional.ofNullable(string)
          .map(s -> (MyInterface) new First()) // casting rather than binding here
          .orElse(new Second())
          .number();






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 3 hours ago









          nullpointernullpointer

          45.6k1097186




          45.6k1097186













          • Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

            – nullpointer
            3 hours ago



















          • Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

            – nullpointer
            3 hours ago

















          Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

          – nullpointer
          3 hours ago





          Opinion: Its just more verbal in terms of casting that would be required for the contracts of map and orElse to be both followed at the same time.

          – nullpointer
          3 hours ago


















          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%2f54238488%2fjava-8-cannot-be-applied-to-interface%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

          Magento 2 controller redirect on button click in phtml file

          Polycentropodidae