Java 8 Optional cannot be applied to interface
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
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 lambda java-8 optional
add a comment |
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 lambda java-8 optional
add a comment |
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 lambda java-8 optional
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 lambda java-8 optional
java generics lambda java-8 optional
edited Jan 18 at 9:13
Nikolas
asked Jan 17 at 14:52
NikolasNikolas
14k53670
14k53670
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
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.
Java *infers* the mapped type to be First
- that's a right formulation.
– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
|
show 4 more comments
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.
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
add a comment |
I would write that without an explicit cast:
Optional.ofNullable(string)
.map(s -> {
MyInterface m = new First();
return m;
})
.orElse(new Second())
.number();
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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 themap
call)
– BackSlash
Jan 17 at 15:00
2
@BackSlash an explicit type cast like withmap(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so ifFirst
mistakenly doesn’t implementMyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with aClassCastException
. In contrast,.<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed ifFirst
actually implementsMyInterface
.
– Holger
Jan 18 at 10:59
add a comment |
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();
1
Opinion: Its just more verbal in terms of casting that would be required for the contracts ofmap
andorElse
to be both followed at the same time.
– Naman
Jan 17 at 17:25
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54238488%2fjava-8-optional-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
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.
Java *infers* the mapped type to be First
- that's a right formulation.
– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
|
show 4 more comments
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.
Java *infers* the mapped type to be First
- that's a right formulation.
– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
|
show 4 more comments
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.
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.
edited Jan 17 at 15:09
answered Jan 17 at 15:01
MichaelMichael
22k83774
22k83774
Java *infers* the mapped type to be First
- that's a right formulation.
– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
|
show 4 more comments
Java *infers* the mapped type to be First
- that's a right formulation.
– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
Java *infers* the mapped type to be First
- that's a right formulation.– Nikolas
Jan 17 at 15:04
Java *infers* the mapped type to be First
- that's a right formulation.– Nikolas
Jan 17 at 15:04
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@Nikolas Yep. It's not a cast as you stated but rather simply explicitly specifying the type.
– Michael
Jan 17 at 15:11
@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
Jan 17 at 20:11
@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
Jan 17 at 20:11
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
@Eugene Read the link in my answer. It ends with "but perhaps with additional enhancements it could be added in the future".
– Michael
Jan 18 at 9:15
3
3
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
@Eugene compare Java 8’s type inference for nested method invocations with what we had before. Extending it to chained method invocations would be a change of a similar magnitude. A big change, but not impossible.
– Holger
Jan 18 at 10:29
|
show 4 more comments
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.
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
add a comment |
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.
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
add a comment |
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.
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.
edited Jan 17 at 17:16
Naman
46k12102205
46k12102205
answered Jan 17 at 14:54
NikolasNikolas
14k53670
14k53670
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
add a comment |
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
4
4
I would say specifying the type parameter explicitly, is better than casting. Something like this:
.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
I would say specifying the type parameter explicitly, is better than casting. Something like this:
.<MyInterface>map(string -> new First())
– marstran
Jan 17 at 14:56
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
@marstran: Agreed, thanks for the hint :)
– Nikolas
Jan 17 at 14:57
3
3
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@Nikolas In what way do you feel it is "shamefully"? Self-answers are perfectly acceptable here.
– glglgl
Jan 17 at 15:01
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
@glglgl: I mean I could put a bit more effort to find the solution :))
– Nikolas
Jan 17 at 15:03
add a comment |
I would write that without an explicit cast:
Optional.ofNullable(string)
.map(s -> {
MyInterface m = new First();
return m;
})
.orElse(new Second())
.number();
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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 themap
call)
– BackSlash
Jan 17 at 15:00
2
@BackSlash an explicit type cast like withmap(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so ifFirst
mistakenly doesn’t implementMyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with aClassCastException
. In contrast,.<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed ifFirst
actually implementsMyInterface
.
– Holger
Jan 18 at 10:59
add a comment |
I would write that without an explicit cast:
Optional.ofNullable(string)
.map(s -> {
MyInterface m = new First();
return m;
})
.orElse(new Second())
.number();
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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 themap
call)
– BackSlash
Jan 17 at 15:00
2
@BackSlash an explicit type cast like withmap(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so ifFirst
mistakenly doesn’t implementMyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with aClassCastException
. In contrast,.<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed ifFirst
actually implementsMyInterface
.
– Holger
Jan 18 at 10:59
add a comment |
I would write that without an explicit cast:
Optional.ofNullable(string)
.map(s -> {
MyInterface m = new First();
return m;
})
.orElse(new Second())
.number();
I would write that without an explicit cast:
Optional.ofNullable(string)
.map(s -> {
MyInterface m = new First();
return m;
})
.orElse(new Second())
.number();
edited Jan 17 at 15:08
answered Jan 17 at 14:57
EugeneEugene
72.5k9103175
72.5k9103175
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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 themap
call)
– BackSlash
Jan 17 at 15:00
2
@BackSlash an explicit type cast like withmap(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so ifFirst
mistakenly doesn’t implementMyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with aClassCastException
. In contrast,.<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed ifFirst
actually implementsMyInterface
.
– Holger
Jan 18 at 10:59
add a comment |
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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 themap
call)
– BackSlash
Jan 17 at 15:00
2
@BackSlash an explicit type cast like withmap(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so ifFirst
mistakenly doesn’t implementMyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with aClassCastException
. In contrast,.<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed ifFirst
actually implementsMyInterface
.
– Holger
Jan 18 at 10:59
1
1
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
Although it makes the lambda body larger, it's a good way to avoid casting, which I am usually against.
– Nikolas
Jan 17 at 14:59
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
Jan 17 at 15:00
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
Jan 17 at 15:00
2
2
@BackSlash an explicit type cast like with
map(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so if First
mistakenly doesn’t implement MyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with a ClassCastException
. In contrast, .<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed if First
actually implements MyInterface
.– Holger
Jan 18 at 10:59
@BackSlash an explicit type cast like with
map(s -> (MyInterface)new First())
, is error prone. The problem is that a type cast can be either, narrowing or widening. While widening is intended, narrowing is still allowed, so if First
mistakenly doesn’t implement MyInterface
(and is not final), the compiler will not object and insert the unintended runtime type cast which will fail with a ClassCastException
. In contrast, .<MyInterface>map(s -> new First())
and the code of this answer both use implicit conversions, which are only allowed if First
actually implements MyInterface
.– Holger
Jan 18 at 10:59
add a comment |
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();
1
Opinion: Its just more verbal in terms of casting that would be required for the contracts ofmap
andorElse
to be both followed at the same time.
– Naman
Jan 17 at 17:25
add a comment |
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();
1
Opinion: Its just more verbal in terms of casting that would be required for the contracts ofmap
andorElse
to be both followed at the same time.
– Naman
Jan 17 at 17:25
add a comment |
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();
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();
answered Jan 17 at 17:21
NamanNaman
46k12102205
46k12102205
1
Opinion: Its just more verbal in terms of casting that would be required for the contracts ofmap
andorElse
to be both followed at the same time.
– Naman
Jan 17 at 17:25
add a comment |
1
Opinion: Its just more verbal in terms of casting that would be required for the contracts ofmap
andorElse
to be both followed at the same time.
– Naman
Jan 17 at 17:25
1
1
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.– Naman
Jan 17 at 17:25
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.– Naman
Jan 17 at 17:25
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54238488%2fjava-8-optional-cannot-be-applied-to-interface%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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