2

I have just implemented some classes:

public abstract class Job<T extends ViewerUnion>{
[...]
}

public abstract class ReturnValueJob<T, S extends ViewerUnion> extends Job<S> {
[...]
}

public class MyReturnJob extends ReturnValueJob<Foo, Baa> {
[...]
}

public class JobExecuter {
public static void execute(List<Job> jobList){
for(Job actJob: jobList){
    actJob.startJob();
}
for(Job actJob: jobList){
    actJob.awaitTimeoutOrFinish();
}
}
}

Now I want to execute this code:

List<Job> list = new LinkedList<MyReturnJob>();
JobExecuter.execute(list);

But Java gives me some error while compiling:

Type mismatch: cannot convert from LinkedList to List

I don't know why because the MyReturnJob is inheriting the Job. If I change the definition of the list to LinkedList<MyReturnJob> list = new LinkedList<MyReturnJob>();

The same error is thrown on JobExecuter.execute(list);

Thanks for your help.

Best regards, Till

2 Answers 2

6

What wrong here??

The problem is not the change from LinkedList to List, but the change in the contained type. Java generics are not covariant, which means you cannot even do:

LinkedList<Job> = new LinkedList<MyReturnJob>();

Details...

For more info, read the "Java theory and practice: Generics gotchas" article. Here its relevant part:

It turns out there's a good reason it doesn't work (...): It would break the type safety generics were supposed to provide. Imagine you could assign a List<Integer> to a List<Number>. Then the following code would allow you to put something that wasn't an Integer into a List<Integer>:

List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

... applied back to context

The article example code can be translated into the context of this question like this:

List<MyReturnJob> li = new LinkedList<MyReturnJob>();
List<Job> ln = li; // illegal
ln.add(new FooJob());

where FooJob is declared as:

public abstract FooJob extends Job<ViewerUnion> {
[...]
}
Sign up to request clarification or add additional context in comments.

3 Comments

@ Oli Charlesworth. Ok, thank you very much. If I change my Listdef to LinkedList<MyReturnJob> list = new LinkedList<MyReturnJob>(); and the JobExecuter to public static void execute(List<? extends Job> jobList){[...] everything will work fine?
@Till: What is GetBetAmountJob?
@ Oli Charlesworth Sorry. Typo, now its MyReturnJob
1

The problem is that you cannot assign collections with different parameterized types, even if those parameterized types would normally be assignable.

What you're probably looking for is something like:

List<Job> list = new LinkedList<Job>();
JobExecuter.execute( list );

public static void execute( List<? extends Job> jobList )
{ ... }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.