Scott Shipp wrote:
Here is the specific question.
You can define a list that holds a supertype, like Number, and then add objects of a subtype, like Integer, to the list:
This both compiles and runs just fine.
Scott Shipp wrote:
But if you try anything like the following two examples, a compile-time error results.
This produces: Type mismatch: cannot convert from List<Integer> to List<Number>
This produces: Type mismatch: cannot convert from ArrayList<Integer> to List<Number>
Scott Shipp wrote:Sorry but what I am asking hasn't been addressed.
I am wondering about the how, not the what. In other words, how does the compiler determine what is allowed to be added to the list, and when is it determined. I was reading Learning Java, Fourth Edition (O'Reilly publishing) which seems to indicate that the compiler merely referees the code during compilation, throwing errors when an unsafe operation is attempted, and if not, then it translates the code to an ArrayList of Object but casts when necessary in the translated code. But I sure would like more specifics, and the title and page of a book where to find it.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Scott Shipp wrote:Winston, it is clear you completely misunderstand what is being asked. I have no problem understanding that subtypes can be assigned to a super type. That is basic OO development. But you should go look at the add method in ArrayList's source and you will see the use of generics there. So I don't know how you think it has nothing to do with generics. Also your code snippet you posted, which is not paraphrased from my post, but rather modified into something different, will not compile because a parameterized type is not a subtype of another just because the supplied parameter is a subtype. A List<Number> would be a subtype of Collection<Number> but a List<Integer> would not be a subtype of List<Number>. If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
Scott Shipp wrote:Winston, it is clear you completely misunderstand what is being asked. I have no problem understanding that subtypes can be assigned to a super type. That is basic OO development. But you should go look at the add method in ArrayList's source and you will see the use of generics there. So I don't know how you think it has nothing to do with generics. Also your code snippet you posted, which is not paraphrased from my post, but rather modified into something different, will not compile because a parameterized type is not a subtype of another just because the supplied parameter is a subtype. A List<Number> would be a subtype of Collection<Number> but a List<Integer> would not be a subtype of List<Number>. If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Scott Shipp wrote:
If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
Henry Wong wrote:
1. In the case of adding Integer, Float, etc. into a List<Number>, Winston is correct. This is basic type checking rules. The List<Number> takes Number instances, so as long as what is being added IS-A Number, it will be allowed.
Henry Wong wrote:
2. In the case of List<Number> being a subclass of Collection<Number>, that is standard subtype rules too. Granted there is generics in the mix, but the generics are the same type, so it doesn't apply here (well, it does apply, but there is nothing that will forbid it).
3. In the case of List<Number> and List<Integer>, this one is affected by the generic rules. And the rule is simple, if the generic type is different, it will not be allowed. This is explained with the simple example that I provided earlier.
Henry Wong wrote:
4. The complexity of generic actually occurs when wildcards are used -- which is not the subject of this topic here. I am only mentioning it here because it may come up. Regardless, the complexity increases with wildcards, so I recommend understanding the simple case (case 3), and how it works with the standard subclassing rules first.
Ulf Lindqvist wrote:
Scott Shipp wrote:
If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
It's the Java Language Specification that determines what compiles and what doesn't, not the "cleverness" of the compiler.
Scott Shipp wrote:Winston, it is clear you completely misunderstand what is being asked.
Winston Gutkowski wrote:I beg to differ. I understood your initial post (or at least - I suspect- the questions that led to it) precisely - because they were exactly the same ones that I had when I started using generics.
Scott Shipp wrote:Hi Ulf! I didn't say cleverness of the compiler, I said underlying implementation and I was referring to the source code of ArrayList's constructor which looks like this (OpenJDK 7-b147)...
Paul Clapham wrote:
Scott Shipp wrote:Hi Ulf! I didn't say cleverness of the compiler, I said underlying implementation and I was referring to the source code of ArrayList's constructor which looks like this (OpenJDK 7-b147)...
Okay, that's what's in one implementation's version of the constructor for ArrayList. But wasn't your question about how the compiler does something? Because the compiler knows nothing and cares nothing about how any constructor or method is implemented. All it knows and cares about is the signatures of those things.
(I apologize, there's been a lot of obfuscation in this thread and I'm now not sure what your question was, exactly. Perhaps a recap of what you understand and don't understand at this point would be helpful?)
Scott Shipp wrote:But I am curious if there is some kind of explanation somewhere about generic polymorphism like in the above example that does work (where I added Integer, Float, Long to an ArrayList<Number>). Obviously the ArrayList implementation in Java uses a generic type, and obviously something within the JVM understands polymorphism of generic types. Otherwise adding Integer, Float, Long etc. to an ArrayList<Number> wouldn't work.
Any points of reference or quick explanation someone can provide about how this works or how it is accomplished?
Ivan Jozsef Balazs wrote:
is simply an ArrayList of Numbers: Numbers can be put into it Numbers can be obtained from there, and Integer, Float, Long are Numbers.
Akin to
Scott Shipp wrote:Sorry but what I am asking hasn't been addressed.
Scott Shipp wrote:the compiler merely referees the code during compilation, throwing errors when an unsafe operation is attempted, and if not, then it translates the code to an ArrayList of Object but casts when necessary in the translated code. But I sure would like more specifics, and the title and page of a book where to find it.
Scott Shipp wrote:Sorry but what I am asking hasn't been addressed.
Winston Gutkowski wrote:I think your basic misconception is that this has anything to do with generics. It doesn't. Nor does anything you've shown us have anything to do with polymorphism; it is simple type checking.
Scott Shipp wrote:Winston, it is clear you completely misunderstand what is being asked.
Scott Shipp wrote:I have no problem understanding that subtypes can be assigned to a super type. That is basic OO development.
Henry Wong wrote:1. In the case of adding Integer, Float, etc. into a List<Number>, Winston is correct. This is basic type checking rules. The List<Number> takes Number instances, so as long as what is being added IS-A Number, it will be allowed.
Scott Shipp wrote:No doubt, man! Keep in mind that I am the one that wrote the code example in order to demonstrate the point that it is allowed. I don't know why you're repeating it back to me?
Steve
Scott Shipp wrote:Also your code snippet you posted, which is not paraphrased from my post, but rather modified into something different, will not compile...
If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Steve Luke wrote:Let me de-obfuscate some. The initial question from the first post was this:
Scott Shipp wrote:But I am curious if there is some kind of explanation somewhere about generic polymorphism like in the above example that does work (where I added Integer, Float, Long to an ArrayList<Number>). Obviously the ArrayList implementation in Java uses a generic type, and obviously something within the JVM understands polymorphism of generic types. Otherwise adding Integer, Float, Long etc. to an ArrayList<Number> wouldn't work.
Any points of reference or quick explanation someone can provide about how this works or how it is accomplished?
Ivan was first to correctly answer the question.
Ivan Jozsef Balazs wrote:
is simply an ArrayList of Numbers: Numbers can be put into it Numbers can be obtained from there, and Integer, Float, Long are Numbers.
Akin to
But you ignored him.
Steve Luke wrote:
Scott Shipp wrote:Sorry but what I am asking hasn't been addressed.
Then you give a description of what a book told you that pretty much covered the topic:
Scott Shipp wrote:the compiler merely referees the code during compilation, throwing errors when an unsafe operation is attempted, and if not, then it translates the code to an ArrayList of Object but casts when necessary in the translated code. But I sure would like more specifics, and the title and page of a book where to find it.
But then you ignored it, asking for another book to tell you what that book told you.
Steve Luke wrote:
If you really want some specifics, I suggest:
http://docs.oracle.com/javase/specs/jls/se7/html/index.html
To narrow your search, start here:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.5
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2
Steve Luke wrote:
There are a lot more places, but I suspect you already are ignoring me at this point. So the links won't help. Why do I guess you will be ignoring me?
Because here is the summary of the rest of this thread:
Remember, you said:
Scott Shipp wrote:Sorry but what I am asking hasn't been addressed.
as you ignored Ivan's response. To which Winston responded:
Winston Gutkowski wrote:I think your basic misconception is that this has anything to do with generics. It doesn't. Nor does anything you've shown us have anything to do with polymorphism; it is simple type checking.
You respond with
Scott Shipp wrote:Winston, it is clear you completely misunderstand what is being asked.
When it is probably closer to the truth that you don't understand what is being said. Ivan, Winston, Henry understand your question. The answer is... well no point being the fourth to say it. Read their posts if you want the answer.
Steve Luke wrote:
Having ignored the important part of Winston's post (how what he talks applies to your question) you dwell only on subtype assignment:
Scott Shipp wrote:I have no problem understanding that subtypes can be assigned to a super type. That is basic OO development.
Henry is next to reiterate what you have been told three times in this post and at least once in a book:
Henry Wong wrote:1. In the case of adding Integer, Float, etc. into a List<Number>, Winston is correct. This is basic type checking rules. The List<Number> takes Number instances, so as long as what is being added IS-A Number, it will be allowed.
Again, you ignore how what he says applies to your question, and instead reply (rather sarcastically in my reading):
Scott Shipp wrote:No doubt, man! Keep in mind that I am the one that wrote the code example in order to demonstrate the point that it is allowed. I don't know why you're repeating it back to me?
Umm. No. You asked a question. Ivan, Henry, and Windston gave you answers. You have ignored the answers. Do you understand that Henry isn't saying "You can put an Integer into a List<Number>" he is saying ... never mind, I won't repeat it again. Re-read if you want the answer.
Winston Gutkowski wrote:And just to add to Steve's excellent post:
Scott Shipp wrote:Also your code snippet you posted, which is not paraphrased from my post, but rather modified into something different, will not compile...
It most certainly will. And what's more, it does exactly what I said it would, which is effectively (and hence the word "paraphrased") what your original assignment does.
If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
Not at all. It behaves precisely as it is specified to; and to understand that, you only need to look at the definition of the constructor. I highly doubt that anything in the implementation source would enlighten you any further.
Winston
Scott Shipp wrote:
If it does compile, it is because of very clever use of generics in the underlying implementation, in the constructor. And that gets at my question of how it all works.
There are no more "hours", it's centi-days. They say it's better, but this tiny ad says it's stupid:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|