Reputation: 372
I'm sorry but I don't know how to express my question in another way than by showing an example :
public interface IStuff<GenericParameter>{}
public interface IWorkWithStuff<GenericParameter>
{
void doSomethingWithStuff(IStuff<GenericParameter> stuff);
}
public interface IBoth<GenericParameter>
extends IStuff<GenericParameter>, IWorkWithStuff<GenericParameter>
{}
public class Test<Both extends IBoth<?>>
{
Both _myBoth;
void test(final Both otherBoth)
{
_myBoth.doSomethingWithStuff(otherBoth);
}
}
This does not compile, could someone explain why ? The error is :
The method doSomethingWithStuff(IStuff) in the type IWorkWithStuff is not applicable for the arguments (Both)
On the other hand, if I name the parameter, it works :
public class Test<NamedParameter, Both extends IBoth<NamedParameter>>
{
Both _myBoth;
void test(final Both otherBoth)
{
_myBoth.doSomethingWithStuff(otherBoth);
}
}
It seems quite similar to me (except that this second solution is not practicable to me in the real case I'm having this problem), can someone explain how this is different ?
Thanks a bunch !
I add that I tested with Java 1.6 and Java 1.8
Answer from awsome gave me a solution.
In the link he pointed there is a section names "Capture helpers" explaining a way to avoid such problems.
In my case, this code works :
public class WorkingTest<Both extends IBoth<?>>
{
Both _myBoth;
void test(final Both otherBoth)
{
final IBoth<?> myBoth = _myBoth;
final IBoth<?> _otherBoth = otherBoth;
rebox(myBoth, _otherBoth);
}
protected <Something, SomethingElse> void rebox(final IBoth<Something> both, final IBoth<SomethingElse> otherBoth)
{
both.doSomethingWithStuff(both);
}
}
It works when types are valid and fails when types are not.
Thanks !
Wooops, there is a mistake in my "solution" :
I wrote
both.doSomethingWithStuff(both);
instead of
both.doSomethingWithStuff(otherBoth);
which doesn't work (and makes sens).
The only solution I found for now is to use cast :
public class WorkingTest<Both extends IBoth<?>>
{
Both _myBoth;
public WorkingTest(final Both myBoth)
{
_myBoth = myBoth;
}
void test(final Both otherBoth)
{
deboxrebox(_myBoth, otherBoth);
}
@SuppressWarnings("unchecked")
protected <CommonParent> void deboxrebox(final Both first, final Both second)
{
final IBoth<CommonParent> _first = (IBoth<CommonParent>) first;
final IBoth<CommonParent> _second = (IBoth<CommonParent>) second;
_first.doSomethingWithStuff(_second);
}
}
At least, it encapsulate the cast, but still isn't very satisfying.
Do you think that using "capture helpers" a better solution can be found ?
Upvotes: 3
Views: 140
Reputation: 2153
Here is a little modification to your example to understand the issue you are facing
public class Test<Both extends IBoth<?>> {
IBoth<?> hello;
void test(final Both otherBoth) {
hello.doSomethingWithStuff(hello); // The method doSomethingWithStuff(IStuff<capture#1-of ?>) in the type IWorkWithStuff<capture#1-of ?> is not applicable for the arguments (IBoth<capture#2-of ?>)
hello.doSomethingWithStuff(hello); // The method doSomethingWithStuff(IStuff<capture#3-of ?>) in the type IWorkWithStuff<capture#3-of ?> is not applicable for the arguments (IBoth<capture#4-of ?>)
}
}
interface IStuff<S> {
}
interface IWorkWithStuff<T> {
void doSomethingWithStuff(IStuff<T> stuff);
}
interface IBoth<U> extends IStuff<U>, IWorkWithStuff<U> {
}
I have also written the errors with the method calls for doSomethingWithStuff. You see that everytime a new call is made capture#xxx changes. The number xxx here says that this is a new unknown type. More about wildcards can be read here http://www.ibm.com/developerworks/java/library/j-jtp04298/index.html
Upvotes: 1
Reputation: 3019
The difference is between the type when you specify ? it is kind of a wild card, while in case of you are specifying a type from which the class Test is extending is predefined i.e. mentioned at compile time, as the java checks for type at compile time. In your first attempt the type is not defined. and hence it is showing an error.
Following link also contains good explanation on the generics.
Upvotes: 0