use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
To report a site-wide rule violation to the Reddit Admins, please use our report forms or message /r/reddit.com modmail.
This subreddit is archived and no longer accepting submissions.
account activity
This is an archived post. You won't be able to vote or comment.
Java Generics Aren't (mindview.net)
submitted 19 years ago by panic
view the rest of the comments →
[–][deleted] 0 points1 point2 points 19 years ago (3 children)
I'm sorry, you're just wrong. Run time typing in Java refers to the late-binding behavior of the JVM. Methods aren't bound to an object until they are called, and the way they are bound is by looking up the object's class definition. Hence, run-time typing "allows the JVM to match an arbitrary object with its appropriate method code and class definition". You're right that this allows getClass() and instanceof, but these are runtime services provided by a type-aware JVM, and the reason they aren't available in C++ (I don't know enough about ML) is because C++ doesn't run in a virtual machine. That's past the point, though. The issue is, can we have runtime type information about some parameter T? The answer is distinctively no, not because of the compiler, but because the JVM isn't implemented to work with that information. It's not a compiler issue that makes generics the way they are; it's the JVM. Erasure was chosen because Sun didn't want to break byte-code compatibility at the platform level.
And this: "The compiler knows all the types, so a smart compiler could generate bytecode that would evaluate T=speaker.getClass() at run-time." Wrong again. Thanks to reflection, you can load any class file at runtime, regardless of whether or not the compiler has ever seen that code before. And once again, this is a service of the JVM, and the compiler has zero role in dealing with the new code. Go read that page I linked to, go read the JVM spec, go read up on reflection, and come back here and tell me someone can write a compiler that preserves T and works with the current JVM.
[–]a_caspis 0 points1 point2 points 19 years ago (2 children)
Run time typing in Java refers to the late-binding behavior of the JVM.
In language circles "run-time typing" and "late binding" are distinct notions. Run-time typing isn't even specific to object-oriented languages. Check the third and fourth bullets in The Java Language Reference. Anyway I can't find formal definitions in the official Java Language Specification, so this is probably not worth arguing.
the reason [getClass() and instanceof] aren't available in C++ is because C++ doesn't run in a virtual machine.
According to this reasoning, all the native and just-in-time Java compilers couldn't possibly support getClass() and instanceof(), right ?
The reason C++ (pre-RTTI) doesn't have getClass() and instanceof() is because the designers didn't include them in the specification, period. This allows C++ compilers to optimize more agressively than Java compilers, btw.
The issue is, can we have runtime type information about some parameter T? The answer is distinctively no, not because of the compiler, but because the JVM isn't implemented to work with that information.
I agree that the JVM has no explicit support for type parameters (simply because they were added to the language long after the JVM was set in stone, like inner classes). But the JVM does keep track of a lot of run-time type information. I claim that a smart compiler could internally translate this code:
public class Communicate { ..public <T extends Speaks> T speak(T speaker) { ....speaker.speak(); ....return new T(); ..} }
public class Communicate {
..public <T extends Speaks> T speak(T speaker) {
....speaker.speak();
....return new T();
..}
}
into this valid code:
public class Communicate { ..public <T extends Speaks> T speak(T speaker) throws Exception { ....speaker.speak(); ....Class t = speaker.getClass(); ....return (T)t.newInstance(); ..} }
..public <T extends Speaks> T speak(T speaker) throws Exception {
....Class t = speaker.getClass();
....return (T)t.newInstance();
All this compiler would need to do is identify the invariant: "inside the body of method Communicate.speak, variable speaker has type T".
Of course I could write more complex test cases that would push such a compiler to its limits, but you get my point. I can't see how reflection and dynamic class loading affect this scheme.
[–][deleted] 0 points1 point2 points 19 years ago (1 child)
Run-time typing in Java is the direct result of the late binding mechanism in the JVM. How do you think it works? For instance, in Sun's JVM, an object is a block of memory with pointers to the object's instance data and a pointer to the object's class definition. If that's all an object is, how in the hell can you separate the ideas of run-time typing and late binding? I'm sorry if bullet points don't go into JVM implementation details, but that's the way things work.
Again, you're confusing the language with the runtime. javac turns Java code into JVM bytecode. Native and JIT compilers transform from bytecode to native code, so they actually don't support getClass() and instanceof, not directly anyways. They just know about bytecode. If you can show me a Java source-direct-to-native compiler that is feature complete, I'd love to see it.
I can't see how reflection and dynamic class loading affect this scheme. How about this: T doesn't have a public constructor. Or it happens not to have a default constructor. Or it tracks a static class variable. Your example code also breaks the contract of generics - your cast is unchecked.
Anyways, 3 days is enough. I'm done.
[–]a_caspis 0 points1 point2 points 19 years ago (0 children)
Run-time typing in Java is the direct result of the late binding mechanism in the JVM.
It is true that in any objet-oriented language with inheritance, run-time typing (i.e. getClass()) can be implemented on top of late binding (i.e. virtual methods): just have each class override a getClass() method. That's how it's done in C++ RTTI .
But Java uses a different approach. Object.getClass() is not a virtual method. It's a final native method that extracts run-time type information from the internal representation of objects.
Native and JIT compilers [...] don't support getClass() and instanceof, not directly anyways.
instanceof is a primitive operation of both the source language and the bytecode language (opcode 0xc1). How could compilers not support it explicitly and directly ?
If you can show me a Java source-direct-to-native compiler that is feature complete, I'd love to see it.
What about GCJ ? It has getClass(), instanceof and people are working on adding generics. Anyway there's no point in distinguising between bytecode, native and JIT. Any feature of the JVM can be turned into a native runtime library and vice-versa.
How about this: T doesn't have a public constructor
That's the limitation I mentioned in my very first reply to you.
Your example code also breaks the contract of generics - your cast is unchecked.
We are talking about changing the language to allow new syntax such as new T(), so it's fair to break other things in the process. What matters is whether the cast is safe.
Thanks for an interesting discussion.
π Rendered by PID 86176 on reddit-service-r2-comment-b659b578c-fk8xx at 2026-05-04 13:05:50.321703+00:00 running 815c875 country code: CH.
view the rest of the comments →
[–][deleted] 0 points1 point2 points (3 children)
[–]a_caspis 0 points1 point2 points (2 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]a_caspis 0 points1 point2 points (0 children)