type safety in java 1.5 (bug or hole?)

Y

York Werres

It would all the same be a nice complement to generics if the 1.5
compiler would indeed issue warnings about user-inserted casts that are
not provably correct. (I.e. those that the compiler cannot simply
ignore). That would give Bracha's comment (that started this confusion)
broad enough scope to no longer be confusing.

I agree very much.

BTW, there's another comment from Bracha in the very same paper that's
confusing (me): He says "The Java virtual machine does not directly support
overriding of methods with different return types. This feature is supported
by the compiler.". What does this mean? Does this mean that the different
return types are gone at run time? Here's an example:

static class A {
static A create() { return new A(); }
public A m(A a) { System.out.println("A->A"); return a; }
}

static class B extends A {
static B create() { return new B(); }
public B m(A a) { System.out.println("A->B"); return (B) a; }
public B m(B b) { System.out.println("B->B"); return b; }
}

public void testOverriding() {
A a_a = A.create(); // static type A, dynamic type A
A a_b = B.create(); // static type A, dynamic type B
B b_b = B.create(); // static type B, dynamic type B

A a2 = a_a.m(a_b); // prints: A->A
A a3 = a_a.m(b_b); // prints: A->A

A a5 = a_b.m(a_b); // prints: A->B <== overriding works
A a6 = a_b.m(b_b); // prints: A->B <== overriding works

B b2 = b_b.m(a_b); // prints: A->B
B b3 = b_b.m(b_b); // prints: B->B
}

public void testReflection() {
try {
System.out.println(
B.class.getMethod("m", new Class[] {A.class}).getReturnType()
== B.class
); // prints: true <== reflection works, too
}
catch (Throwable t) {
throw new RuntimeException("Laufzeitfehler", t);
}
}

So there's obviously some runtime support for overriding methods with a
different return type, because in this example both the overriding and the
reflection worked. Then what did Bracha mean?

2004-05-24, York.
 
N

Neal Gafter

York said:
So there's obviously some runtime support for overriding methods with a
different return type, because in this example both the overriding and the
reflection worked. Then what did Bracha mean?

What he meant is that it works by virtue of javac generating a bunch of methods
that makes it work, not because covariant return types are supported in the VM.
 
R

Roedy Green

So there's obviously some runtime support for overriding methods with a
different return type, because in this example both the overriding and the
reflection worked. Then what did Bracha mean?

Genericity is also done without anything in the JVM. The additional
level of type checking and automatically generated casts is all done
at compile time.
 
Y

York Werres

Genericity is also done without anything in the JVM. The additional
level of type checking and automatically generated casts is all done
at compile time.

That's my point. Genericity doesn't work with reflection because there is no
genericity at run time. But there are covariant return types at runtime as
my test example showed. Bracha's statement about the covariant return types
being, too, completely handled by the compiler itself with no support of the
runtime system, sounded to me as if there are no covariant return types with
reflection as there is no genericity with reflection. But there are, so
Bracha must have meant something else.

Concerning genericity, I don't quite understand why there's no runtime
support, anyway. I mean "-source 1.5"-compiled classes don't run in the 1.4
runtime and "-source 1.5 -target 1.4" is not allowed by the compiler and
"-source 1.5 -target jsr14" works fine with some genericity examples on the
1.4 runtime but it failes for example with this one:

public void test7() {
List<Integer> list1 = new LinkedList<Integer>();
list1.add(4);
System.out.printf("%d", list1.get(0));
}

So there's no way to use a 1.5 language feature in the 1.4 runtime. Why then
type erasure as a means to implement genericity if you need a new runtime,
anyway?

25.05.04, York.
 
N

Neal Gafter

York said:
That's my point. Genericity doesn't work with reflection because there is no
genericity at run time. But there are covariant return types at runtime as
my test example showed.

Your example shows that javac faithfully provides the illusion of runtime
support for covariant returns.
Bracha's statement about the covariant return types
being, too, completely handled by the compiler itself with no support of the
runtime system, sounded to me as if there are no covariant return types with
reflection as there is no genericity with reflection. But there are, so
Bracha must have meant something else.

I believe you understood him correctly.
So there's no way to use a 1.5 language feature in the 1.4 runtime. Why then
type erasure as a means to implement genericity if you need a new runtime,
anyway?

For backward compatibility. Specifically, so that existing libraries can
interoperate with generified code, and so that existing sources can be
retrofitted with generics without breaking compatibility with existing code with
which it interoperates.
 

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,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top