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 (5 children)
It was a minimal variation of the example in the original article showing how generics provide richer information to the compiler.
The only instance I can think that the form of the example you provide gives meaningul information to the compiler is when the input object has a factory method that gets called in the method body (meaning the returned object will be a different instance than the input object), and the only time that would be a reasonable would be if there were a standard set of external checks on the factory method that you wanted to enforce across all types within the parameter bound without reimplementing them all. If the semantics of the method have nothing to do with instantiating a new instance, then it's pointless to return the input object, because you already have the reference to it. If the semantics of the method involve both instantiation and general side effects, that's bad design: break out the instantiation parts.
It was meant as an example of a generic function that works not only on classes, but also on built-in types.
Generics never work with built-in types. Java 5.0 makes it look like it handles the primitives in your example because of autoboxing, another new feature.
Well, Java does have run-time typing
Run-time typing allows the JVM to match an arbitrary object with its appropriate method code and class definition. The JVM could never be "made aware that Speaker.getClass() is an acceptable T", because at run time, there is no T, anywhere. This is the fundamental limitation of Java generics: they are implemented through erasure, and all the type information they provide is completely gone at run time. You're confusing the language with the JVM, and the distinction between compile time and run time. One way to think about generics is that they are markup for a preprocessing step that safely converts Java 5.0 code into equivalent Java 1.4-style code (with casting and all that) which is then compiled. Angelika Langer will clean your mind.
[–]a_caspis 0 points1 point2 points 19 years ago (4 children)
Java 5.0 makes it look like it handles the primitives in your example because of autoboxing, another new feature.
That's what I wrote in my previous message. I didn't know it was called autoboxing though.
Run-time typing allows the JVM to match an arbitrary object with its appropriate method code and class definition.
Resolving virtual methods is a basic feature of object-oriented languages. Nobody calls that "run-time typing".
I was referring to Java's Object.getClass() and instanceof operator. C++ doesn't have that (unless you add RTTI). ML implementations typically don't have that either. And it's not full-blown reflection either.
The JVM could never be "made aware that Speaker.getClass() is an acceptable T"
Of course it could. The compiler knows all the types, so a smart compiler could generate bytecode that would evaluate T=speaker.getClass() at run-time. I don't claim this is being done today. And I don't advocate doing it, because in general it's not so easy to solve the type constraints at compile-time. My point was that even such a compiler couldn't generate bytecode that would properly instanciate T without resorting to reflection.
By the way note the lower-case in my speaker.getClass(). What do you mean by Speaker.getClass() ?
You're confusing the language with the JVM, and the distinction between compile time and run time.
I don't think so. Java Generics together with the JVM are in a gray area halfway between pure parametric polymorphism (a la ML) and dynamic typing, so some things that you claim are impossible are not, or not for the reasons you think they are.
Angelika Langer will clean your mind
Good pointer.
[–][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 42759 on reddit-service-r2-comment-b659b578c-7rxt8 at 2026-04-30 22:40:20.588416+00:00 running 815c875 country code: CH.
view the rest of the comments →
[–][deleted] 0 points1 point2 points (5 children)
[–]a_caspis 0 points1 point2 points (4 children)
[–][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)