I've failed to google this problem. Why would this line produce a compilation error.
wrapper.doSmth(wrapper.getCurrent());
I'm using java 7.
public class App {
Wrapper<?> wrapper;
class Generic<T>{
}
class Wrapper<T>{
Generic<T> current;
public void doSmth(Generic<T> generic){
}
public Generic<T> getCurrent(){
return current;
}
}
public void operation(){
wrapper.doSmth(wrapper.getCurrent());
}
}
The error is:
Error:(25, 24) java: method doSmth in class App.Wrapper<T> cannot be applied to given types;
required: App.Generic<capture#1 of ?>
found: App.Generic<capture#2 of ?>
reason: actual argument App.Generic<capture#2 of ?> cannot be converted to conf.App.Generic<capture#1 of ?> by method invocation conversion
Using generics in your Java development can help you detect issues during compile time rather than being confronted by them at run time. This gives you greater control of the code and makes the syntax easy to follow. Generics also improves code readability.
Generics are checked at compile-time for type-correctness. The generic type information is then removed in a process called type erasure. For example, List<Integer> will be converted to the non-generic type List , which ordinarily contains arbitrary objects.
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.
The compilation error should be something along the lines of "capture of ? #1 is not compatible with capture of ? #2". The cause of this error is that wrapper
is a Wrapper<?>
.
The compiler sees that the wrapper.getCurrent()
returns a Generic<?>
, and that wrapper.doSmth
takes a Generic<?>
as a parameter. But it won't equate the two ?
wildcards, even if we can see that they come from the same instance and should be the same.
One solution here is to make the App
class generic, so you can replace the wildcard.
public class App<T> {
Because of the fact that Generic
and Wrapper
are inner classes, T
is still in scope, so you don't need to declare a generic type parameter for them any more.
Wrapper wrapper;
class Generic{
}
class Wrapper{
Generic current;
public void doSmth(Generic generic){
}
public Generic getCurrent(){
return current;
}
}
public void operation(){
wrapper.doSmth(wrapper.getCurrent());
}
}
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