Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » Java Development Tools (JDT) » Java Generics Bug in Eclipse 3.6?(Methods with differing signatures result in same erasure and are flagged as errors)
Java Generics Bug in Eclipse 3.6? [message #642330] Tue, 30 November 2010 19:55 Go to next message
No real name is currently offline No real nameFriend
Messages: 3
Registered: November 2010
Junior Member
This code compiles under jdk1.6.0_22:

package mypackage

import java.util.List;
import java.util.concurrent.Callable;

public class CommandExecutor {
    public static <V> List<V> execute(List<Callable<V>> tasks, int threads) {
	// do something	with callables
	return null;
    }

    public static void execute(List<Runnable> tasks, int threads) {
	// do something with runnables
    }
}


Eclipse Version: 3.6.1.r361_v20100909-9gF78GrkFqw7GrsZnvz0JWNTeb6fue6896L Build id: M20100909-0800 claims that both execute methods have the same erasure:

execute(List<E>, int) 


and claims this is an error and puts a red x on the file but Eclipse 3.5 has no issues with the above code.

Is this an Eclipse 3.6 bug, or is there some compatibility setting I need to use in 3.6? I tried switching to Java 1.6 compliance from 1.5 compliance but it made no difference and I saw nothing under the Java Compiler Errors/Warnings preferences that seemed relevant. I was planning to submit a bug, but figured I should ask here first since I'm new to 3.6. Thanks.

Jim
Re: Java Generics Bug in Eclipse 3.6? [message #642357 is a reply to message #642330] Tue, 30 November 2010 23:51 Go to previous messageGo to next message
Eclipse UserFriend
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 #642376 is a reply to message #642330] Wed, 01 December 2010 05:36 Go to previous messageGo to next message
Satyam Kandula is currently offline Satyam KandulaFriend
Messages: 444
Registered: July 2009
Senior Member
As Jim had mentioned 3.6.1 has the correct behavior. Look at https://bugs.eclipse.org/bugs/show_bug.cgi?id=289247 for more information.
Re: Java Generics Bug in Eclipse 3.6? [message #642487 is a reply to message #642330] Wed, 01 December 2010 14:46 Go to previous messageGo to next message
No real name is currently offline No real nameFriend
Messages: 3
Registered: November 2010
Junior Member
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.

Jim


Re: Java Generics Bug in Eclipse 3.6? [message #642515 is a reply to message #642487] Wed, 01 December 2010 16:01 Go to previous messageGo to next message
Mauro Molinari is currently offline Mauro MolinariFriend
Messages: 281
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.
Re: Java Generics Bug in Eclipse 3.6? [message #642542 is a reply to message #642330] Wed, 01 December 2010 17:53 Go to previous messageGo to next message
No real name is currently offline No real nameFriend
Messages: 3
Registered: November 2010
Junior Member
Thanks for your reply Mauro, you're right I need to read more about Java generics. I didn't realize that erasure meant the type info was being completely removed in the byte code and resulted in the old untyped List for backward compatibility. I assumed generics worked like C++ templates.
Re: Java Generics Bug in Eclipse 3.6? [message #642563 is a reply to message #642542] Wed, 01 December 2010 19:15 Go to previous message
Michael Pellaton is currently offline Michael PellatonFriend
Messages: 289
Registered: July 2009
Senior Member
I recommend Gilad Bracha's paper on the topic:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
Previous Topic:XML printing in Detail Formatters using Xerces
Next Topic:How to get the canonical name of an entity, from its Binding
Goto Forum:
  


Current Time: Fri Dec 19 02:20:46 GMT 2014

Powered by FUDForum. Page generated in 0.14853 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software