It is currently 21 Oct 2018, 23:54
   
Text Size

Generics & 'Type Erasure': disingenuous documentation?

Non-Application Specific Programming Stuff

Moderator: CCGHQ Admins

Re: Generics & 'Type Erasure': disingenuous documentation?

Postby fortion322 » 08 Sep 2013, 20:47

Show us an example then...as code.

I presume you have encountered something that does cause a problem in real life, and not merely as a mental exercise, that you could use here to illustrate your concerns.

Then explain how you would restructure the byte code and JVM to handle this case (note, the array problem not the generics one) that does not cause backward compatibility problems. And maybe then you might see that this is rather unlikely to be tackled anytime soon.
fortion322
 
Posts: 18
Joined: 05 Sep 2013, 12:58
Has thanked: 0 time
Been thanked: 0 time

Re: Generics & 'Type Erasure': disingenuous documentation?

Postby cyberion » 08 Sep 2013, 20:51

fortion322 wrote:Show us an example then...as code.

I presume you have encountered something that does cause a problem in real life, and not merely as a mental exercise, that you could use here to illustrate your concerns.

Then explain how you would restructure the byte code and JVM to handle this case (note, the array problem not the generics one) that does not cause backward compatibility problems. And maybe then you might see that this is rather unlikely to be tackled anytime soon.
I think you are still looking at things in isolation and trying to separate one issue from the other, when they are joined at the hip.

We have already seen a SIMPLE example of the problem from the Java Trail...

Java Code:

public static void faultyMethod(List<String>... l) {
// Valid
Object[] objectArray = l;
objectArray[0] = Arrays.asList(new Integer(42));
// ClassCastException thrown here
String s = l[0].get(0);
}

If this happened in real life, I would need to get at the line labeled "valid", because that assignment is the most specific one that relates to the incompatibility, and is amenable to the compiler. From there I can check what objectArray is doing that is violating l or any of its potentially many aliases.

In a far more complex scenario, there may be many such candidates aliasing l in complex ways. The compiler should flag them.

If I get a runtime exception, because the exception doesn't happen at the point of heap pollution, all I get to know is that something corrupted l. And the compiler only flags whole methods and says, "it's in one of these, chief".

So I would have to examine the whole of the code: the method referenced by the runtime exception and methods in its call graph that were flagged, instead of specific variables. The "don't code crap argument doesn't really stand". In practice, you are often faced with debugging complex code you did not write yourself.
cyberion
 
Posts: 15
Joined: 08 Sep 2013, 17:48
Has thanked: 0 time
Been thanked: 0 time

Re: Generics & 'Type Erasure': disingenuous documentation?

Postby fortion322 » 08 Sep 2013, 20:53

But as I said, that example is bollocks code.
If I saw that in some real code I would take it out back and have it shot.

How should the compiler know that the above is not a valid cast?
And what changes are required in the runtime to make a runtime exception occur at the point of assignment? Presumably every "array[i] = something" will have to have a check the "something" is allowed in the underlying object?

This is still a mental exercise. Do you have a concrete example?

If you don't then maybe you might realise why this is not likely to be dealt with.
fortion322
 
Posts: 18
Joined: 05 Sep 2013, 12:58
Has thanked: 0 time
Been thanked: 0 time

Re: Generics & 'Type Erasure': disingenuous documentation?

Postby silly freak » 11 Sep 2013, 17:55

cyberion wrote:Java 5 and onwards allows type variables and parametrized types to be used in declarations. 'Type Erasure' is a grandiose term describing a "process" whereby the compiler eliminates all references to these type variables and parameters in the generated byte code. The reason given is to make Java 5 and onwards compatible with earlier versions of Java, which do not support Generics.

What I suspect is the case is that Generics has been added as incomplete, "design time only" support for parameterized types, which the compiler IGNORES at the point of actual generation of byte code -- hardly what I would call a "process of type erasure". I suspect that the compiler simply does nothing different, and generates the same byte code as the equivalent raw types. The only compiler difference is in its design time validation.

Backward compatibility is a good reason for allowing aliasing of raw types with generic types. It is not a good reason for allowing heap pollution. Heap pollution causes pending runtime exceptions which should be trapped immediately. This suggests that parametrized type information is important at runtime, even when you require backward compatibility.

Can anyone prove me wrong, perhaps by creating a concise example of a generic type that compiles into different byte code from its equivalent raw type?
I have not read the full thread; as far as I can tell, you were arguing about whether the JVM design is good or not; I don't claim to be an expert field, but I have some comments about statements in your original post which are wrong.

This dependes on your definition of "generation of byte code". The bytecode, as my definition goes, is the whole class file. In a class file compiled with generics, additional information is present in comparison to the equivalent raw code, obviously. The best evidence is when you compile code against java.util.List, which is a generic class you only have in the form of bytecode. If the information was lost, you could not base your own generic code on precompiled generic code. Thus, the Java compiler does not simply discard generic information, neither for validating your classes, nor for generating the bytecode.

If you only consider the opcodes which are part of methods bytecode, then, yes, you could create a raw class which generates the same "bytecode". An elegant way to put it is that *objects* don't have a generic type, but fields, types and methods do. Note that the compiler is not the only tool which can access this information. The information is not only preserved in the bytecode, but also at runtime. Type is the superinterface for all types, including generic types and you can e.g. query a Field for its generic type.

There are patterns which come close to objects having generic types at runtime, e.g. used by the Collections.checked*() methods. However, this does only work if you have an actual class which you can add code to; it does not work for arrays. Arrays are where generics break down, but if you write good code, this does not matter. Bad design is not when things can break (otherwise you'd have to argue that C++ is designed badly because you can declare destructors nonvirtual, or that C is designed badly because it allows arbitrary pointer manipulation); bad design is when things break when you do normal stuff. Casting a List<String>[] to Object[] to inject a rogue object is not normal - passing an array you still need to a method you don't trust is not normal in the first place. You can't control what is put into an array, independently of whether you use generics. If you don't trust the code, give them an object that mediates between your data and them. If you don't need the data afterwards, simply catch the exception. Generics or not, a rogue method will be able to throw a ClassCastException.
___

where's the "trust me, that will work!" switch for the compiler?
Laterna Magica - blog, forum, project, 2010/09/06 release!
silly freak
DEVELOPER
 
Posts: 598
Joined: 26 Mar 2009, 07:18
Location: Vienna, Austria
Has thanked: 93 times
Been thanked: 25 times

Previous

Return to General Programming

Who is online

Users browsing this forum: No registered users and 1 guest


Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 10 minutes)
Most users ever online was 279 on 11 Jul 2013, 22:03

Users browsing this forum: No registered users and 1 guest

Login Form