Reputation: 73
Below is the code where I declared two methods whose return type are bounded parameters but one is based on interface whereas other is based on a class. In the test() method, assigning return type to String fails for method where bounded parameter extends from Class which is expected, but compiler doesn't throw error when the bounded parameter is based on interface. Can you explain why does this happen?
import java.io.FileInputStream;
import java.util.function.Predicate;
public class Dummy
{
<T extends Predicate<String>> T getBoundedByInterface()
{
return null;
}
<T extends FileInputStream> T getBoundedByClass() {
return null;
}
public void test()
{
String compilationError = getBoundedByClass(); //Expected
String works = getBoundedByInterface(); //No compilation error. Why?
}
}
Upvotes: 2
Views: 63
Reputation: 178263
The Java compiler will determine if the variable type can satisfy the generic return type of the method called. With a class such as FileInputStream
, it knows that no class can be both a FileInputStream
and a String
because a class can't inherit from more than one class, so this is disallowed. Additionally we know that String
is also final
, but that doesn't figure into the compiler's logic.
However, with an interface, it's possible for a subclass to extend the bound and be a subclass of another class.
class Thing extends FileInputStream implements Predicate<String> {
// Implementation
}
This compiles for that reason.
Thing works = getBoundedByInterface();
Notice that it also works with String
because the compiler doesn't take into account that String
is final
.
Upvotes: 2