I have a java interface like this
public interface MyInterface<T> {
public <V extends T> V get(String key, Bundle bundle);
}
please note the <V extends T>
type parameter of the method.
Then I have a class MyFoo implements MyInterface
class MyFoo implements MyInterface<Object> { // Object because can be any type
@Override public <V> V get(String key, Bundle bundle) {
return new Other();
}
}
So when I now have a class like this:
class Bar {
public Other other;
public Other setOther(Other other);
}
Then I want to take MyFoo
to set Other
in a Bar
instance:
MyFoo foo = new MyFoo();
Bar bar = new Bar();
bar.other = foo.get();
This works perfectly. Type can be determined by java generics. No additional cast is needed.
However, if I want to use bar.setOther()
then the type can not be determined:
MyFoo foo = new MyFoo();
Bar bar = new Bar();
bar.setOther(foo.get()); // Fails
Then I get the following compile error:
error: incompatible types: Object cannot be converted to Other
I don't understand why this doesn't work for the bar.setOther( foo.get() )
method but works when accessing the field directly bar.other = foo.get()
Any idea how to solve that without adding an extra cast like bar.setOther( (Other) foo.get() )
There may be times when you want to restrict the types that can be used as type arguments in a parameterized type. For example, a method that operates on numbers might only want to accept instances of Number or its subclasses. This is what bounded type parameters are for.
Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class. These are known as bounded-types in generics in Java.
Multiple BoundsBounded type parameters can be used with methods as well as classes and interfaces. Java Generics supports multiple bounds also, i.e., In this case, A can be an interface or class. If A is class, then B and C should be interfaces. We can't have more than one class in multiple bounds.
What is the difference between a wildcard bound and a type parameter bound? A wildcard can have only one bound, while a type parameter can have several bounds. A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter.
In an assignment, the Java compiler knows what return type to use for the method by looking at the type that it is being assigned to. So to answer your question
Any idea how to solve that without adding an extra cast like
bar.setOther( (Other) foo.get() )
?
This is a way in which you can do that:
Other value = foo.get();
bar.setOther(value);
There is another way, which looks worse but still doesn't have a cast:
bar.setOther(foo.<Other>get());
And a third alternative: switch to Java 8; in Java 8 you can just do bar.setOther(foo.get());
.
For Java 7, the rules for this type inference are specified in JLS section 15.12.2.8:
If any of the method's type arguments were not inferred from the types of the actual arguments, they are now inferred as follows.
If the method result occurs in a context where it will be subject to assignment conversion (§5.2) to a type S, then [...]
A method result is subject to assignment conversion if it is used in an assignment expression.
- Otherwise, the unresolved type arguments are inferred by invoking the procedure described in this section under the assumption that the method result was assigned to a variable of type
Object
.
If the unresolved type argument is used in a method whose result is not used in an assignment expression, then the type argument is interpreted as if the method result was assigned to a variable of type Object
. So this means in this case that if the result of the get()
method is not assigned to a variable, then the return type of the get()
method is taken to be Object
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With