Understanding Generics: Mission (Im)possible?

I came across this weird thing that I'm not sure about whether this is a javac or IDEA bug.
The following code compiles fine, but is not considered correct by IDEA. Who is right? Is
this really legal code?

interface I {
T get(Class key); } class Base implements I { public Object get(Class key) { return null; } } There's another weird thing that doesn't make much sense to me: Set]]> set = new HashSet();

This seems to be perfectly legal but shouldn't IDEA show a warning about that? I think code like
this points to an incomplete generification but I couldn't find an inspection that reports it.

Thanks,
Sascha

17 comments
Comment actions Permalink

I came across this weird thing that I'm not sure about whether this is
a javac or IDEA bug. The following code compiles fine, but is not
considered correct by IDEA. Who is right? Is this really legal code?

interface I {
<T> T get(Class<T> key);
}
class Base implements I {
public Object get(Class key) {
return null;
}
}


It's legal simply because generic types can always be converted to equivalent
raw types in any context, for backwards compatibility.

There's another weird thing that doesn't make much sense to me:

Set<String> set = new HashSet();

This seems to be perfectly legal but shouldn't IDEA show a warning
about that? I think code like this points to an incomplete
generification but I couldn't find an inspection that reports it.


IDEA should be showing you a warning for that. I don't have IDEA open right
now but I know it shows me warnings for similar statements. You could also
enable the inspection "Raw use of generic type," which would pick up more
of these.

Thanks,
Sascha




0
Comment actions Permalink

"Raw use of generic type" will pick up the fact that you used a HashSet without specifying a type argument, but won't pick up the fact that the implicit cast is weird and disturbing, but legal. "Conversion from raw type to parameterized type" and vice versa would be cool things, but don't exist at present. I'm afraid I'm just learning the generic semantics as well, and having much the same surprises as Sascha. There's clearly room for several inspections to ease the transition, but I don't honestly know what they would be. Yet. I'm now at the point where I can begin accepting suggestions (i.e. actually using generics in my plugin code, and not totally clueless), so bring 'em on.

--Dave Griffith

0
Comment actions Permalink

Sacha,
this is indeed our bug. I'll look at it next week for sure.

Eugene.

"Sascha Weinreuter" <sascha.weinreuter@NOSPAM-cit.de> wrote in message
news:d5ime3$p69$1@is.intellij.net...

I came across this weird thing that I'm not sure about whether this is a

javac or IDEA bug.

The following code compiles fine, but is not considered correct by IDEA.

Who is right? Is

this really legal code?

>

interface I {
<T> T get(Class<T> key);
}

>

class Base implements I {
public Object get(Class key) {
return null;
}
}

>

There's another weird thing that doesn't make much sense to me:

>

Set<String> set = new HashSet();

>

This seems to be perfectly legal but shouldn't IDEA show a warning about

that? I think code like

this points to an incomplete generification but I couldn't find an

inspection that reports it.
>

Thanks,
Sascha



0
Comment actions Permalink

While I can imagine the use of

Set set = new HashSet(); as a result of saving to type information which seems redundant here because when looking at the code it's clear what it means. But there are other instances which are kinda dangerous, namely when a method takes a parameterized type but you're allowed to pass a raw type with possibly wrong content. Maybe an inspection that reports such usages might have an option to ignore raw object instantiations, but report things like Set foo = new HashSet(); ... Set set = foo; because there's a good chance that the code at "..." adds something to foo other than Strings. On the other hand, excluding object instantiation isn't really safe either because of this: Set ints = new HashSet(); Set]]> foo = new HashSet(ints);

Weird stuff.

Sascha

0
Comment actions Permalink

Thanks Eugene, here's the JIRA link:
http://www.jetbrains.net/jira/browse/IDEA-1846

Sascha

0
Comment actions Permalink


"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:298560632510660175124880@news.jetbrains.com...

I came across this weird thing that I'm not sure about whether this is
a javac or IDEA bug. The following code compiles fine, but is not
considered correct by IDEA. Who is right? Is this really legal code?

>

interface I {
<T> T get(Class<T> key);
}
class Base implements I {
public Object get(Class key) {
return null;
}
}

>

It's legal simply because generic types can always be converted to

equivalent

raw types in any context, for backwards compatibility.


Actually things are not so simple, e.g. inheriting the other way, i.e.
parameterized method implementing raw is prohibited.

Eugene.


0
Comment actions Permalink

"Sascha Weinreuter" <sascha.weinreuter@NOSPAM-cit.de> wrote in message
news:d5je57$mnr$1@is.intellij.net...

While I can imagine the use of

>

Set<String> set = new HashSet();

>

as a result of saving to type information which seems redundant here

because

when looking at the code it's clear what it means. But there are other

instances

which are kinda dangerous, namely when a method takes a parameterized type

but

you're allowed to pass a raw type with possibly wrong content.

>

Maybe an inspection that reports such usages might have an option to

ignore raw

object instantiations, but report things like


All situations where type safety may be violated are part of Java 5.0 type
system and reported by javac with -warnunchecked flag.
IDEA also has a unchecked warning category in inspections settings. Please
check that you've this category on if you like to to be aware of type
unsafety.
Eugene.


0
Comment actions Permalink

Eugene Vigdorchik (JetBrains) wrote:

IDEA also has a unchecked warning category in inspections settings. Please
check that you've this category on if you like to to be aware of type
unsafety.


Thanks, I didn't find this one. Maybe Generics/JDK 1.5 specific stuff could be
given a more descriptive name or even be put into an own category? A pre-configured
inspection profile that includes all JDK 1.5-only inspection would probably OK as
well.

Shouldn't this "Unchecked warning" be enabled by default? Would have avoided some
of the confusion in the first place ;)

Sascha

0
Comment actions Permalink

Eugene Vigdorchik (JetBrains) wrote:

>> IDEA also has a unchecked warning category in inspections settings.
>> Please check that you've this category on if you like to to be aware
>> of type unsafety.
>>

Thanks, I didn't find this one. Maybe Generics/JDK 1.5 specific stuff
could be given a more descriptive name or even be put into an own
category? A pre-configured inspection profile that includes all JDK
1.5-only inspection would probably OK as well.

Shouldn't this "Unchecked warning" be enabled by default? Would have
avoided some of the confusion in the first place ;)

Sascha


I agree, it should be enabled by default. It's important for any Java 5 developer.


0
Comment actions Permalink


"Sascha Weinreuter" <sascha.weinreuter@NOSPAM-cit.de> wrote in message
news:d5nsq1$tg4$1@is.intellij.net...

Eugene Vigdorchik (JetBrains) wrote:

IDEA also has a unchecked warning category in inspections settings.

Please

check that you've this category on if you like to to be aware of type
unsafety.

>

Thanks, I didn't find this one. Maybe Generics/JDK 1.5 specific stuff

could be

given a more descriptive name or even be put into an own category? A

pre-configured

inspection profile that includes all JDK 1.5-only inspection would

probably OK as

well.

Nice idea, definitely deserves a request to JIRA:)

Shouldn't this "Unchecked warning" be enabled by default? Would have

avoided some

of the confusion in the first place ;)

I thought it is...

Eugene.


0
Comment actions Permalink

Eugene Vigdorchik (JetBrains) wrote:

I thought it is...


You're right, it is. I'm using the same configuration since the first Irida build
I used by importing my old 4.5.x configuration. Just checked with a clean config
and the inspection is indeed enabled now by default.

I think it would still be a good idea if there were a way to see all JDK 1.5
related inspections at one glance. Maybe a preset filter that would show such
inspections that aren't in the same category but are related in some other way?

Sascha

0
Comment actions Permalink

I'm more in favor of their own category. Give it a name, and I'll move mine there tomorrow.

--Dave Griffith

0
Comment actions Permalink

Dave Griffith wrote:

Give it a name


Generics issues?

Bas

0
Comment actions Permalink

Naw, it's also got to cover stuff like unnecessary boxing and unboxing and for or while loop replaceable by for-each.

J2SDK5.0 migration issues, maybe.

--Dave

0
Comment actions Permalink

Dave Griffith wrote:

Naw, it's also got to cover stuff like unnecessary boxing and
unboxing and for or while loop replaceable by for-each.


Ah, my mistake, I thought this discussion was about generics only.

J2SDK5.0 migration issues, maybe.


I believe it is just called JDK (again, since version 5.0?). "JDK 5.0
migration issues" would be my suggestion then.

Bas

0
Comment actions Permalink

Bas Leijdekkers wrote:

I believe it is just called JDK (again, since version 5.0?). "JDK 5.0
migration issues" would be my suggestion then.


I agree. An alternative could be "JDK 5.0 (migration|feature) support". Makes
sense at least for things like loops that are replaceable by foreach, etc. But
I don't have any strong feelings about it, as long as a n00b in these things is
able to find them quickly ;)

Sascha

0
Comment actions Permalink

I think it should definitely be called "Java 5.0 migration issues," it's
about Java language, not the JDK

Bas Leijdekkers wrote:

>> I believe it is just called JDK (again, since version 5.0?). "JDK 5.0
>> migration issues" would be my suggestion then.
>>

I agree. An alternative could be "JDK 5.0 (migration|feature)
support". Makes sense at least for things like loops that are
replaceable by foreach, etc. But I don't have any strong feelings
about it, as long as a n00b in these things is able to find them
quickly ;)

Sascha




0

Please sign in to leave a comment.