The problem with setting the parameters of the parameter Bounded Type

I have a java interface like this

public interface MyInterface<T> { public <V extends T> V get(String key, Bundle bundle); } 

note the parameter of type <V extends T> 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:

 class Bar { public Other other; public Other setOther(Other other); } 

Then I want to take MyFoo to set Other to an instance of Bar :

 MyFoo foo = new MyFoo(); Bar bar = new Bar(); bar.other = foo.get(); 

It works great. Type can be determined using java generics. No additional cast is required.

However, if I want to use bar.setOther() , then the type cannot be determined:

 MyFoo foo = new MyFoo(); Bar bar = new Bar(); bar.setOther(foo.get()); // Fails 

Then I get the following compilation error:

error: incompatible types: object cannot be converted to another

I do not understand why this does not work for the bar.setOther( foo.get() ) method, but it works with direct access to the bar.other = foo.get() field

Any idea how to solve this problem without adding an extra listing like bar.setOther( (Other) foo.get() )

+6
source share
1 answer

In the job, the Java compiler knows what type of return value to use for the method by looking at the type to which it is assigned. Therefore, to answer your question

Any idea how to solve this problem without adding an extra rush like bar.setOther( (Other) foo.get() ) ?

This is the way you can do this:

 Other value = foo.get(); bar.setOther(value); 

There is another way that looks worse, but still does not have a cast:

 bar.setOther(foo.<Other>get()); 

And the third option: transition to Java 8; in Java 8 you can just do bar.setOther(foo.get()); .

For Java 7, the rules for outputting this type are specified in the JLS section 15.12.2.8 :

If any of the arguments of the method type has not been inferred from the types of the actual arguments, they are now inferred as follows.

If the result of a method occurs in the context where it will be assigning (Β§5.2) to type S, then [...]

The result of the method is subject to conversion of the assignment, if it is used in the assignment expression.

  • Otherwise, arguments of an unresolved type are inferred by calling the procedure described in this section, assuming that the result of the method was assigned to a variable of type Object .

If an unresolved type argument is used in a method whose result is not used in the assignment expression, then the type argument is interpreted as if the result of the method was assigned to a variable of type Object . Thus, in this case, this means that if the result of the get() method is not assigned to a variable, then the return type of the get() method is considered Object .

+3
source

All Articles