The problem is that your source type is not compatible with the type of the target type, but that is what your method declaration requires.
Your copyFrom
method is declared as
public void copyFrom(T source);
Which means that the generic type argument for the object in target must be the same as that of the source, namely both must be of some type T
.
Of course, if you use a wildcard type like ?
there is no way the compiler can tell if the ?
is of the same type T
in both source and target, after all it could be different, for instance.
CopyInterface<?> target = new Foo();
CopyInterface<?> source = new Bar();
Above ?
represents two different types CopyInterface<Foo>
and CopyInterface<Bar>
. So, as you can see, when you use ?
you lose type information that later that compiler don't have available to make important decisions and you get those compiler errors.
Coming back to the copyFrom
method, in a case like this the compiler cannot know if the ?
corresponds to the type T
that the method copyFrom(T source)
expects, hence your compiler error.
You would not have this problem if both source and target were of the same type.
For instance, if you had an implementation of your interface like this:
class Foo implements CopyInterface<Foo> {
@Override public void copyFrom(Foo source){}
}
Then you would not have problem doing this:
Foo target = new Foo();
Foo source = new Foo();
target.copyFrom(source);
In this case T
is Foo
in both source and target, and this is compatible with the signature of your method.
Since it looks like you only read from the source, then you could also relax the rules in your interface by declaring it as follows:
interface CopyInterface<T extends CopyInterface<T>> {
void copyFrom(CopyInterface<? extends T> source);
}
Then your implementation might look like
class Foo implements CopyInterface<Foo> {
@Override public void copyFrom(CopyInterface<? extends Foo> source){}
}
Then you could do
CopyInterface<Foo> target = new Foo();
CopyInterface<Foo> source = new Foo();
target.copyFrom(source);
But as long as you use wildcard types here, I doubt you can manage to make it work.