Another generics foul-up

I

Ian Pilcher

This compiles:

class Foo
{
boolean foo(Object o)
{
class Local
{
public boolean equals(Object o)
{
return o != null && (o instanceof Local);
}
}

Local local = new Local();
return local.equals(o);
}
}

This doesn't:

class Foo<T>
{
boolean foo(Object o)
{
class Local
{
public boolean equals(Object o)
{
return o != null && (o instanceof Local); // ******
}
}

Local local = new Local();
return local.equals(o);
}
}

javac complains that the marked line contains an "illegal generic type
for instanceof". I've encountered similar problems before with inner
classes:

class Foo<T>
{
class Bar {}

boolean isBar(Object o)
{
return o != null && (o instanceof Bar);
}
}

javac will issue the same cryptic error message. What it's failing to
communicate is that an inner class of a parameterized type is itself
implicitly parameterized. So "o instanceof Bar" really means
"o instanceof Foo<T>.Bar".

In this case, the workaround is pretty obvious. "o instanceof Foo.Bar"
works. The Eclipse compiler calls this the "raw form".

So what's the raw form of a Local class name? AFAIK, that's up to the
compiler. javac generates names like Foo$1Local, and it is in fact
possible to use this name -- "o instanceof Foo$1Local". Talk about a
recipe for brittle code!

Is there a solution I'm missing -- other than calling
getClass().instanceOf(o)?
 
T

Thomas Hawtin

Ian said:
So what's the raw form of a Local class name? AFAIK, that's up to the
compiler. javac generates names like Foo$1Local, and it is in fact
possible to use this name -- "o instanceof Foo$1Local". Talk about a
recipe for brittle code!

Using instanceof on a local class seems nuts to me. If you really must
do that, you could always declare a (static) interface and have the
local class implement that.

Tom Hawtin
 
C

Chris Smith

Thomas Hawtin said:
Using instanceof on a local class seems nuts to me. If you really must
do that, you could always declare a (static) interface and have the
local class implement that.

It doesn't seem nuts to me... but unfortunately, it still doesn't work
with generics due to type erasure. At least, it doesn't seem any more
nuts than any other use of instanceof. The notion of an opaque value
whose type is unknown outside of a limited context shouldn't be too
foreign to anyone.

Indeed, the only work-around appears to be to promote the type to a
nested class or interface. That's not terrible, but it is less than
ideal.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
M

Mike Schilling

Chris Smith said:
It doesn't seem nuts to me... but unfortunately, it still doesn't work
with generics due to type erasure. At least, it doesn't seem any more
nuts than any other use of instanceof. The notion of an opaque value
whose type is unknown outside of a limited context shouldn't be too
foreign to anyone.

Indeed, the only work-around appears to be to promote the type to a
nested class or interface. That's not terrible, but it is less than
ideal.

If the worst thing generics do is break local classes, they're OK with me.
 
I

Ian Pilcher

Bruce said:
not got into generics yet. any good? worth learning?

Unavoidable.

I doubt that many commercial shops have made the jump to Java [1.]5 yet,
but it's going to happen eventually. And it's not really possible to
avoid them in 1.5 (unless you want to turn off every compiler warning).
 
A

Adam Warner

not got into generics yet. any good? worth learning?

Sun's compiler now warns that lots of traditional Java code is potentially
unsafe and unchecked. This is propaganda that hurts Sun's message about
Java being a safe language--especially when only a subset of these
warnings can be resolved using generics.

Sun expects you to write additional code to make the warnings go away. And
if you can't make the warnings go away to write even more code to suppress
the warnings that they created to browbeat you into using generics in the
first place.

All the additional code you write (some of it unintelligible) will result
in fewer run time class cast exceptions. As such errors hardly ever escape
testing it's not a good bargain. Plus, class cast exceptions seem to be
far less common than null pointer exceptions, an issue unaddressed by Java
generics (thankfully. I hate to think how I would satisfy the compiler
that, for example, a circular list cannot contain null).

For all this extra work and digestion of an insane number of special
cases where generics don't in fact work you end up with code that doesn't
run an iota faster. Extra information you were forced to supply to shut up
the compiler is thrown away before the JVM can use it for optimisation
purposes. Or before you can make full use it for introspective purposes.

You can expect the amount of practical software development to decline as
thousands of hours are devoted to eliminating compiler warnings and
rewriting legacy code instead of developing new functionality.

In summary, this is good for the industry.

Regards,
Adam
 
B

Bruce Lee

You can expect the amount of practical software development to decline as
thousands of hours are devoted to eliminating compiler warnings and
rewriting legacy code instead of developing new functionality.

In summary, this is good for the industry.

Regards,
Adam

so stemming innovation is a good thing?
 
R

Roedy Green

Sun's compiler now warns that lots of traditional Java code is potentially
unsafe and unchecked. This is propaganda that hurts Sun's message about
Java being a safe language--especially when only a subset of these
warnings can be resolved using generics.

You are using safe in two different contexts. Generics safe means
finding out about a problem at compile time rather than run time.

Application safe means that programs don't have undefined behaviour
when you have null pointers or subscripts out of range.

Applet safe means a unsigned Applet you invite into your computer
can't write on your hard disks go pestering other computers on the
net.
 
A

Adam Warner

You are using safe in two different contexts. Generics safe means
finding out about a problem at compile time rather than run time.

Therefore "Generics safe" is a misleading term for "satisfies the static
type checker". Code that satisfies the extra static type checks is not
automatically safe and so-called unchecked code is always checked. It is
the run time environment that ensures safety...
Application safe means that programs don't have undefined behaviour when
you have null pointers or subscripts out of range.

That is the code cannot subvert the relevant run time environment.
Applet safe means a unsigned Applet you invite into your computer can't
write on your hard disks go pestering other computers on the net.

That is the code cannot subvert the relevant run time environment.

"The code compiles without needing to suppress warnings" is not a useful
definition of safe. I think Sun is nuts claiming that traditional Java
code is potentially unsafe when it is the JVM's job to enforce safety.
Sun are the ones using safe in a misleading context.

Regards,
Adam
 
D

Daniel Dyer

not got into generics yet. any good? worth learning?

Good on the whole in as much as it shifts one class of runtime errors to
being compile-time errors, which means they will be detected quickly even
on rarely exectuted paths. But once you get past the basics there are
some annoying limitations due to the fact that generics were bolted onto a
mature language rather than designed in from the start. The two main
problems I have encountered are not being able to access generic
information at runtime and not being able to create generic arrays.

Dan.
 
E

Ed Kirwan

Sun expects you to write additional code to make the warnings go away.
Regards,
Adam


I've been cranking Google but the mince is too fatty: does anyone know
of any tool that might help reformat pre-generics into generics-ised code?

I know nothing could do the job 100%, but it couldn't be beyond the
bounds of possibility to parse some Collections in the source code (with
their tell-tale, casted getter methods) back to their declarations and
smack them both with some angle-brackets. (An oversimplification, I know.)

Even if the tool bailed where confused, a 50% success rate would help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top