|
Re: Java Generics Bug in Eclipse 3.6? [message #642357 is a reply to message #642330] |
Tue, 30 November 2010 23:51 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NOSPAM.ibm.com
Hi,
I don't know about Eclipse 3.5 vs. 3.6, but that code is technically
invalid I think, in 1.5 or 1.6. Because if you removed the generics
(which is what erasure does) the two methods have the same name and the
same parameters but different return types. This is invalid because
there is no way to know which to call.
If you remove the generics you get this:
public class CommandExecutor {
public static List execute(List tasks, int threads) {
return null;
}
public static void execute(List tasks, int threads) {
}
}
--
Thanks,
Rich Kulp
|
|
|
|
|
Re: Java Generics Bug in Eclipse 3.6? [message #642515 is a reply to message #642487] |
Wed, 01 December 2010 16:01 |
Mauro Molinari Messages: 285 Registered: July 2009 |
Senior Member |
|
|
Il 01/12/2010 15:46, james.mckinley@cengage.com ha scritto:
> Callable and Runnable are concrete types though, why wouldn't the
> compiler be able to know which method to call? Is it that if a method or
> class is written using generics (i.e. List) then the compiler can never
> differentiate between specific types of that class (i.e. List<String>
> vs. List<Integer>) when used as arguments? That seems overly restrictive
> to me, if the execute functions above were truly written with List<E> as
> the first argument then of course I understand the problem, but I
> would've thought it perfectly valid if concrete types were used.
> If I write:
>
>
> public static void test(List<String> arg) {
> // do stuff
> }
>
>
> and then call it with the wrong type of list
>
>
> public static void main(String[] args) {
> List<Integer> list = new ArrayList<Integer>();
> test(list);
> }
>
>
> the compiler (and eclipse) will properly flag this call of the test
> method in main as invalid since String and Integer are different types,
> so it seems to me it should be able to tell in the case of the
> CommandExecutor above as well. What am I missing? Thanks again.
IMHO I think you should go through some deeper documentation about
generics. Generics are a way to let you write typesafe code, but once
the code is compiled they are erased, in order to produce bytecode which
is backward-compatible with Java<5. Under this point of view
List<String> and List<Integer> are both just List once compiled, this is
why the compiler rejects your code, although from a plain compilation
point of view it would be possible to differentiate between a call to
test(List<String>) and test(List<Integer>).
However, please note that if you write this:
public class Test
{
public static void test(List<String> a)
{
for(Object element : a)
System.out.println(element);
}
public static void main(String[] args)
{
List<Integer> b = new ArrayList<Integer>();
test((List) b);
}
}
This code is perfectly compiling and working, although you are actually
calling test(List<String>) by passing it a List<Integer>. The compiler
warns you about the potential error, but this highlights a bit how
things work under the cover. Suppose it would be legal to have another
test(List<Integer>), the picture would be even more complicated.
I think the Java Language Specification has introduced some constraints
here to avoid ambiguities. The Eclipse and Oracle compilers are now
complying better with the specification.
Maybe someone will be able to provide you a more theoretical and
exhaustive explanation.
HTH
Mauro.
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03822 seconds