Derik Davenport wrote:I read once that removing primitives was proposed as a future update in Java, possibly as early as Java 9 or 10. I don't think that is going to happen because a lot of people still need that for performance reasons and it would break backwards compatibility.
Derik Davenport wrote:Obviously primitives and generics don't mix. So you end up with parallel amalgamation structures, Arrays and Lists respectively. And while we are at it, Arrays and Generics especially don't mix, and Bloch's book recommends preferring Lists to Arrays. Does that mean I should prefer boxed types primitives? I would say so. So maybe one point for boxed types.
Derik Davenport wrote:But if that notion can even be proposed, it suggests that someone feels that using primitives in normal code should be avoided.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
But the eight wrapper classes were written before generics were (re)introduced into Java®. I think they had to be written because there was a need for methods operating on primitives and so one could store the equivalent of primitives in Collections.Jesper de Jong wrote: . . .
You can't use primitives for generic type parameters, and that is the main (maybe even the only) reason why the wrapper classes exist. . . .
Campbell Ritchie wrote:In C# I believe they used to use primitives but have changed the language so all values are exposed to the user as objects.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:
But hey, maybe the compiler is smarter than I give it credit for...
Winston
Surely that is the same as the JLS says?Dave Tolls wrote: . . . The compiler is . . . unboxing, incrementing and reboxing. . . .
Campbell Ritchie wrote:Surely that is the same as the JLS says?
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Campbell Ritchie wrote:I am getting confused here. Integer remains immutable in Java®...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Winston Gutkowski wrote:And, as I've said, my main complaint is not so much that it does it; but that it does it silently - even in cases that I, for one, didn't expect it to do it at all.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Yes, you have.Winston Gutkowski wrote: . . .
Hope I've explained myself. . . .
The JVM is programmed on the assumption its users know how it worksA few minutes ago, I wrote: . . . much more serious.
Winston Gutkowski wrote:I redouble my objection to autoboxing.
Always use primitives for arithmetic, not boxed objects.
Ivan Jozsef Balazs wrote:I ask myself whether autoboxing creates more problems than it solves.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
This was exactly the conversation I wanted to read. A bunch of experts talking about the ramifications of using boxed vs primitive types. I feel humbled. Truly.Campbell Ritchie wrote:I think we end up going back to the earlier post with the quotes from Bloch's book. Maybe we need a new design principle
Always use primitives for arithmetic, not boxed objects.
Campbell Ritchie wrote:Bloch's example took 1.7s with longs and 14s with Longs when I tried it a few seconds ago.
Jesper de Jong wrote:The idea is to remove primitives from the Java programming language, but not from the JVM.
This would suggest that more syntactic sugar is needed. So if ++myInteger works, and I think someone suggested that += and *= also work, then why now allow "==" on Integer to compare the values of the Integer? I realize that means you have just overloaded the == operator, but if you can overload the others, why not this? Well the could possibly a problem where you REALLY wanted to compare if two instances of Integer were really the same instance, but in that rare circumstance it would have been sufficient to cast one or the other to Object before doing the compare. But I haven't thought this through, maybe there is some huge problem with that idea. There would probably be objections if we tried to do it now!Campbell Ritchie, quoting J. Bloch wrote:... the == operator does not operate on intValue() (for Integers) or similar but looks for reference identity.
Also Bloch says you can't use default values; the default value for an Integer field is null, so any attempt to unbox that will cause a NullPointerException.
Why? Didn't we do the same with String? Specifically I can writeWinston Gutkowski wrote:I just don't like the fact that they've changed a supposedly immutable object into a "mutable" one. And it's done silently.
Perhaps there should indeed be a warning about that, just like the warning you get when comparing String with ==.but not arithmetic or anything that involves boxing AND unboxing in the same "operation"
I don't think anything about that design principle, since I created it. I only know things about it (I am sure thousands of other people have created virtually identical rules). That doesn't say anything about boxing for adding to Lists, so this sort of thing is all right:I am sure that is what boxing was intended for.Derik Davenport wrote: . . .
Cambell, do you think that design rule implies that all other activities should be done with boxed types?
. . .
Some languages so that sort of thing: the == operator is overloaded to check for String equality rather than identity in C#, but as you say it would be hard to do after the fact.Derik Davenport wrote: . . . So if ++myInteger works, and I think someone suggested that += and *= also work, then why now allow "==" on Integer to compare the values of the Integer? I realize that means you have just overloaded the == operator, but if you can overload the others, why not this? . . . But it might be hard to do it now after the fact.
Where do you get that warning? Is it from an IDE? I don't think the javac tool provides such warnings.Perhaps there should indeed be a warning about that, just like the warning you get when comparing String with ==.but not arithmetic or anything that involves boxing AND unboxing in the same "operation"
No, that is not mutability. This is what mutability would look like:-Remember that most built-in immutable non‑wrapper classes have mutable counterparts; in this case the mutable counterpart would be StringBuilder.Derik Davenport wrote: . . . I can write
Line 5 sure makes it look like String a is mutable. . . .
Derik Davenport wrote:Didn't we do the same with String? Specifically I can write...
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
That looks very similar toWinston Gutkowski wrote: . . . not arithmetic or anything that involves boxing AND unboxing in the same "operation". . . .
Yeah, you are right. I was thinking about that on the way home. YOurs is a much better example of what mutability look like. No one would expect my assert to pass.Campbell Ritchie wrote:No, that is not mutability. This is what mutability would look like:-
I choose my wording very carefully. Your introduction to that design principle was a bit vague. You said "I think we end up going back to the earlier post with the quotes from Bloch's book. Maybe we need a new design principle" That sounded to me as if you might have been attributing those words to Bloch, and also possibly some earlier post. I couldn't find such a quote in his book, but didn't look very hard. . I think your principle is valid, but it doesn't say much outside the context of this discussion. For instance, it doesn't say anything about using (or not using) boxed types at any other time. What I am looking for is a design principle that tells me (and other programmers) how to design new API's.I don't think anything about that design principle, since I created it.
That said, I have since looked at some more APIs (including the Guava libraries) and it is almost a universal practice to build API's with primitves. Indeed, within the implementation code I saw, most programmers seem to use the following rule.Use boxed types for all variables EXCEPT where performance requires that you use primitives.
. My first rule looks good on paper, but even I wouldn't advocate it given the overwhelming precedent to the contrary.use primitives for all variables EXCEPT where they must interact with generic types.
I know we can go round and round in circles agreeing with one another, but what about the == operator. Bloch (loc cit) gives an example where the behaviour of < > and == on an Integer object gives unexpected and incorrect results.Derik Davenport wrote: . . . Use boxed types for all variables EXCEPT where performance requires that you use primitives. . . .
You mean in the bad old days before they got their act together to implement generics which other languages had implemented from the beginning, you could only put Objects into Collections. The problem arose because one had to cast the Objects retrieved and that was not type‑safe. Boxing allows one to appear to add primitives to Collections (as I showed earlier).Rico Felix wrote: . . .
Before generics the language used inheritance to implement generic code . . .
Campbell Ritchie wrote:Boxing allows one to appear to add primitives to Collections (as I showed earlier).
Campbell Ritchie wrote:That looks very similar to … Always use primitives for arithmetic, not boxed objects.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6 - OCEJPAD 6
How To Ask Questions How To Answer Questions
Campbell Ritchie wrote:Bloch (loc cit) gives an example where the behaviour of < > and == on an Integer object gives unexpected and incorrect results.
Perhaps more syntactic sugar should have been made to address this at the time of release. For example, they could have made it an error to create an instance of [Number] that was null. They could have overloaded == when 2 boxed types were involved. But maybe that was impossible for other reasons I haven't considered.Rob Spoor wrote:If you compare a primitive with an object, the object is always unboxed. That can lead to some surprising NullPointerExceptions.
but the fact is that I don't know ... and I don't really want to have to know either
SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6 - OCEJPAD 6
How To Ask Questions How To Answer Questions
Rob Spoor wrote:In other words, they couldn't do either.
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here
Absolutely. They can't do either of them now. But if they had done them at the time they implemented the wrapper classes, then they could have done this. Sadly, until they implemented autoboxing the value of this would not have been apparent.Rob Spoor wrote:In other words, they couldn't do either.
Oh man that is so true. So very, very true.Winston Gutkowski wrote:And isn't it interesting that offering something as "simple" as autoboxing...is fraught with so many difficulties?
Don't get me started about those stupid light bulbs. |