|
Sponsored Links
Resources
Enterprise Java Research Library
Get Java white papers, product information, case studies and webcasts
|
|
Message #128802
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
I can see what's happening here and it's rather like the 1+1=2 type problem made even more complex with the addition of "valueOf" being hidden from view. This takes me back to the bad ol' days of C++ and operator overloading. While it does make some things simpler to read it can cause some VERY nasty problems. I'm very much for progress but I'm not sure this is a good thing, it also raises an interesting question about how to teach Java now although Generics is going to eclipse this one.
-John- CTO, C24
|
|
Message #128805
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
This shouldn't be any type of surprise. .NET users have been blogging on this same issue in their platform.
|
|
Message #128809
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
From one of the comments: Integer j1 = 127; Integer j2 = 127; System.out.println( j1==j2); //Works!!!
Integer k1 = 128; Integer k2 = 128; System.out.println( k1==k2); //Doesn't Work!!!
Integer w1 = -128; Integer w2 = -128; System.out.println( w1==w2); //Works!!!
Integer m1 = -129; Integer m2 = -129; System.out.println( m1==m2); //Doesn't Work!!! This is nuts and pretty much unacceptable.
|
|
Message #128813
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
They should all fail but
sun did some special things for object where there are a small set of values so that when you execute identitymap.put(1, "foo") and then identitymap.get(1) you actually get "foo" back, which you really shouldn't. However, this doesn't break any existing behavior and looking for "broken" corner cases isn't really the point of autoboxing anyway (a pretty pointless feature for keys of map, useful for values)
|
|
Message #128817
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
I think that there is something to be said for autoboxing in most cases. It doesn't reduce object creation, but it reduces code complexity. However, like everything else, if you can use primitives, do it. If you can't, don't. Simple rule. Here's some examples:
// Can't use primitives, let the compiler autobox HashMap map = new HashMap(); map.put(1, "One");
// Can use primitives, autoboxing doesn't make sense here int count = 0; for (int i = 0; i < len; i++) { count += getResults(i); }
There are a lot of places that primitives are 100% acceptable and autoboxing doesn't clear anything up at all. Not to mention that it slows it down quite a bit. Would you want your OpenGL 3D engine using Double instead of double? I wouldn't because creating the Double objects is eventually going reduce my frame-rate. Here's the count example with autoboxing:
// Autoboxing seems dumb here Integer count = 0; for (int i = 0; i < len; i++) { count += getResults(i); }
This is guarenteed to create at most len objects (worse-case). So, just like the old language debate, use the best solution for the problem.
|
|
Message #128818
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
This is nuts and pretty much unacceptable. Is it? I agree that it reads horribly the way it's written here. But I'd argue that it's not written correctly. We've all been taught since day one that objects should never be compared using ==. With autoboxing, my literal 2 becomes an object by way of assigning it to an object (Integer) reference.
We can't have primitive semantics with objects. Otherwise, how would we ever be able to determine if it is the same instance (assuming we cared)? Functionality would be lost. The alternative would be to always resolve a value (say 127) from a cache of integers...but then how would constructors (e.g. new Integer(127)) work?
IMHO, this implementation is correct. Using == to compare objects is incorrect.
Cheers, Clinton
|
|
Message #128819
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
They should all fail but
sun did some special things for object where there are a small set of values so that when you execute identitymap.put(1, "foo") and then identitymap.get(1) you actually get "foo" back, which you really shouldn't. However, this doesn't break any existing behavior and looking for "broken" corner cases isn't really the point of autoboxing anyway (a pretty pointless feature for keys of map, useful for values) Actually, that has nothing to do with Sun. Maps use hashcode and equals for storing and retrieving values. Any JVM will work with this code as long as Integer correctly implements the hashcode and equals methods (which Sun's JVM does). The autoboxing creates an Integer object and the contract of Integer is that hashcode returns the intValue and equals ensures that the two Integer objects have the same intValue. Doesn't matter if == works or not in this case.
|
|
Message #128820
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
This is nuts and pretty much unacceptable. Is it? I agree that it reads horribly the way it's written here. But I'd argue that it's not written correctly. We've all been taught since day one that objects should never be compared using ==. With autoboxing, my literal 2 becomes an object by way of assigning it to an object (Integer) reference.We can't have primitive semantics with objects. Otherwise, how would we ever be able to determine if it is the same instance (assuming we cared)? Functionality would be lost. The alternative would be to always resolve a value (say 127) from a cache of integers...but then how would constructors (e.g. new Integer(127)) work? IMHO, this implementation is correct. Using == to compare objects is incorrect.Cheers,Clinton To take this a step further, if you want to use == with Objects, use the new typesafe enums. Wrapper classes aren't enums, so don't use ==. All enums are examples of the flyweight pattern where their is a cache of possible values and you always get one of those. This means that == works fine for them because it is impossible to get anything BUT one of those values in the cache.
(I wish Boolean was an enum) ;)
|
|
Message #128829
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
We can't have primitive semantics with objects. Pardon my ignorance, but isn't that a lot of what autoboxing is? Behind the scenes, everything is all objects, but then those objects are manipulated with primitive semantics?
Overall, I think this is a pretty silly feature.
|
|
Message #128830
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
This is nuts and pretty much unacceptable. Is it? Yes :-) I agree that you shouldn't use == for objects, but having inconsistencies, like above, is IMO unacceptable behavior. I wonder if it's even consistent across JVMs. Nonetheless, it's the blurring between objects and primitives that will be guaranteed to cause problems in the future. At the very least, the behavior should be predictable.
|
|
Message #128845
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
To me teaching Java to beginners as a pure OO language is a pretty noble ideal. Java already has a precedent of selective operator overloading, in '+' for Strings. What I was wondering was if Java could extend the set of Objects it defines operator overloading for (still not allowing custom operator overloading) to the primitive wrappers. The JVM is perfectly capable of converting '==' calls to '.equals'.
Any of the autoboxing-related surprises mentioned here are surprises only if you're expecting primitive behavior and get Object behavior or vice versa, and consequently is more of a problem area for peopel who have already learnt Java in its present 'primitive' avatar. If you learnt to treat everything as an Object, why would you be surprised?
The performance cost of using Objects over primitives may be important for certain applications, but not generally, and it goes down with time. Case in point - the cost of using String + in place of StringBuffer .append has gone down enough that with the latest releases, for most uses, Josh Bloch's Effective Java does not advocate it if it makes things harder to understand, unless this part is known to be a bottleneck.
|
|
Message #128848
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
but having inconsistencies, like above I guess I don't find it inconsistent, or at least not as inconsistent as the alternative would be. In each case the result is true or false based on whether the reference is pointing to the same object instance or not.
When dealing with objects, == does not compare values. Doing so _would_ be inconsistent.
The same situation has always held true for strings:
String s1 = "True"; String s2 = "True"; s1 == s2 == true //compiler uses one instance for string literals
String s3 = new String("False"); String s4 = new String("False"); s3 == s4 == false //two forced instances
String s5 = "True"; String s6 = "Tr" + "ue"; s5 == s6 == true //compiler evaluates and uses same instance
String s7 = "False"; String sx = "F"; String s8 = sx + "alse"; s7 == s8 == false //compiler won't evaluate where a second reference is involved
These values are all "equal". But == will return true or false based on _how_ the values were set.
Stick to .equals(), and enjoy the remaining features of autoboxing.
Cheers, Clinton
|
|
Message #128854
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
I guess I don't find it inconsistent, or at least not as inconsistent as the alternative would be. In each case the result is true or false based on whether the reference is pointing to the same object instance or not. When dealing with objects, == does not compare values. Doing so _would_ be inconsistent. I agree, and the more I think about it, the more I'm inclined to disagree with my earlier comment. It's probably too early to tell what the impact of auto-boxing will be, but there's a fine line between obscuring and simplifying. I would have been happy with auto-casting on things like this:<code> Integer i1 = map.get(0); </code> That's the only place I always thought the compiler should know what to do since it's so obvious. Other than that, I haven't heard anyone ask for auto-boxing. Anyone know what really prompted the auto-boxing feature?
|
|
Message #128884
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
From one of the comments: Integer j1 = 127;Integer j2 = 127;System.out.println( j1==j2); //Works!!!Integer k1 = 128;Integer k2 = 128;System.out.println( k1==k2); //Doesn't Work!!!Integer w1 = -128;Integer w2 = -128;System.out.println( w1==w2); //Works!!!Integer m1 = -129;Integer m2 = -129;System.out.println( m1==m2); //Doesn't Work!!! This is nuts and pretty much unacceptable. Yes - I agree that this is nuts.
The programmer should be able to work on the language without understanding how the language is implemented. If everybody needed to understand quantum theory before using microwaves, then you will be able to count the number of microwaves sold in one hand.
The language designers need to create a language that lets programmers focus on what they want to do, not how it is implemented. Or are we planning to trek back towards assembly.
|
|
Message #128888
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
Well, but in case of autoboxed Integers, it IS a little inconsistent .. it works something like this :
String s1 = "True"; String s2 = "True"; s1 == s2 == true //compiler uses one instance (precached) for string literals
String s3 = "True, but little longer one"; String s4 = "True, but little longer one"; s1 == s2 == false //compiler does not precache longer values ..
This is the same as with 127 and 128 values for Integers, with 127 those 2 objects are the same, for 128 are created different objects. So, if it works different based only on the value, than it is really confusing.
|
|
Message #128890
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
I'm a teacher too (in france). For me that not a surprise because the spec (JLS3) said that boxing wrapper from -128 to 127 are cached.
|
|
Message #128891
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing in Java is bad
The more I think about autoboxing, the less I like it. One of the blogs had a really good example:
Integer i = new Integer(2); Integer j = new Integer(2); assertTrue(i >= j); // success assertTrue(i <= j); // success assertTrue(i == j); // failure!
The problem with autoboxing in Java is that the variable i is both an object reference AND a primitive depending on the context. Because == is defined for object references, the last line doesn't work as the lines before it, where i and j where treated as primitives. This ambiguous behaviour will cause lots of programming errors.
|
|
Message #128901
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
This is the dawn of Java
I would not claim there is no real world scenario for this problem. This actually would have to be proven and I can't see a chance for that to happen. The examples are the proof against it, actually. Programmer skill sets do not count in that matter.
The point is: there is some artificial boundary set up where the language is not consistent in between. I think this will become a major issue to acceptance of the language soon. Taken the exsample given, financial institutions will call red alert, whatever the practical relevance it has.
The caching is a practical, typical IT focused approach to performance but it's braking the language's inner logic. And that's the very frightening part of it.
|
|
Message #128926
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
String s3 = "True, but little longer one"; String s4 = "True, but little longer one"; s1 == s2 == false //compiler does not precache longer values .. All string literals are supposed to be unique within a special pool. So (IIRC) the above is incorrect. It's not the compiler, it's the JVM.
Peace,
Cameron Purdy Tangosol, Inc. Coherence: Clustered JCache for Grid Computing!
|
|
Message #128945
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
So, if it works different based only on the value, than it is really confusing. It's only confusing if == is misused. The point is that == is NOT for comparing values of objects (however they were set), and it likely never will be.
In Java, operators are overloaded for convenient String manipulation (albeit with a few caveats). So, we've always been able to do this:
String s1 = "A" + "B";
But we still needed to compare like this:
s1.equals("AB")
Now that we have autoboxing extensions, we can do this (not previously possible):
Integer i = 2 + 2;
But we STILL need to compare like this:
i.equals (4)
Consider it a coincidence that:
Integer j1 = 127; Integer j2 = 127; System.out.println( j1==j2); //Works!!!
In Java, == has never been used for comparing values, and autoboxing does not change that (nor should it).
Cheers, Clinton
|
|
Message #128947
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
We can't have primitive semantics with objects. Pardon my ignorance, but isn't that a lot of what autoboxing is? I don't believe so. Autoboxing is simply about automatically wrapping, or "boxing" your primitives with their corresponding object wrapper classes (int -> Integer). Once they have "become" objects, they are bound by the same rules as all other objects. That means that == won't compare the values, but will compare the references.
Cheers, Clinton
|
|
Message #128951
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
String s3 = "True, but little longer one";String s4 = "True, but little longer one";s1 == s2 == false //compiler does not precache longer values .. Actually it does. Try it. You'll blow the maximum string literal length limit and it will always come out true. In fact, it makes *more* sense for longer strings to keep the class file size down.
Cheers, Clinton
|
|
Message #128953
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
String s3 = "True, but little longer one";String s4 = "True, but little longer one";s1 == s2 == false //compiler does not precache longer values .. All string literals are supposed to be unique within a special pool. So (IIRC) the above is incorrect. It's not the compiler, it's the JVM.Peace,Cameron Purdy Cameron, I think you might be referring to something completely different. The above example is regarding the way string literals are handled by the compiler. If they are the same within the class file, the compiler will use only one instance of it. Try it out:
String s1="Cameron"; String s2="Cameron"; System.out.println(s1==s2);
Compile that code and look at the class file. "Cameron" will only appear once, and this code will print true (obviously).
Cheers, Clinton
|
|
Message #128957
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
It's only confusing if == is misused. The point is that == is NOT for comparing values of objects (however they were set), and it likely never will be. Of course, but autoboxing is still extremely confusing. For example, <= and >= works fine for Integer objects, but == does not work, ie a <= b && a >= b does not imply a == b. I don't know of any other programming language that works this way, and it goes against all mathematical logic.
|
|
Message #128965
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Actually...
I used identitymap not map for exactly the reasons you state. As you say, map wouldn't work but identityhashmap http://java.sun.com/j2se/1.4.2/docs/api/java/util/IdentityHashMap.html works as I have described. This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). Gotcha. Missed that. Still, that's just a bad call now isn't it? IdentityMap was intended for flyweights and pretty much nothing else. That map is ideal for Enums, but pretty much bad for every other object in the entire JVM, unless you guarentee flyweight semantics.
In fact it tells you that:
This class is not a general-purpose Map implementation! While this class implements the Map interface, it intentionally violates Map's general contract, which mandates the use of the equals method when comparing objects. This class is designed for use only in the rare cases wherein reference-equality semantics are required.
Same with Strings as with Integers and for that matter primitives. Let's say that it didn't autobox the int, you would still have a value residing in a memory location for the put and an entirely different memory location for the get. Since this uses reference-equality semantics, it is the same as using the old C++ &value syntax (it uses the memory location). Therefore, even if the JDK supported primitives as keys, it still shouldn't work!
|
|
Message #128970
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
string references
If they are the same within the class file, the compiler will use only one instance of it. Try it out:
String s1="Cameron"; String s2="Cameron"; System.out.println(s1==s2);
Compile that code and look at the class file. "Cameron" will only appear once, and this code will print true (obviously). I agree with everything you said, except the fact that == is true for this example (whether or not they are even in the same class!) is because the Java specification says that they will be ==.
Peace,
Cameron Purdy Tangosol, Inc. Coherence: Clustered JCache for Grid Computing!
|
|
Message #128988
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
It's only confusing if == is misused. The point is that == is NOT for comparing values of objects (however they were set), and it likely never will be.In Java, operators are overloaded for convenient String manipulation (albeit with a few caveats). So, we've always been able to do this: String s1 = "A" + "B";But we still needed to compare like this: s1.equals("AB") Now that we have autoboxing extensions, we can do this (not previously possible): Integer i = 2 + 2;But we STILL need to compare like this: i.equals (4) Slap me if I'm missing something here 8-) - so now we are supposed to remember to use i.equals(4) because 2 screens back we wrote Integer i = 2 + 2, not int i = 2 + 2?
|
|
Message #129011
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
we are supposed to remember to use i.equals(4) because 2 screens back we wrote Integer i = 2 + 2, not int i = 2 + 2? You should know whether you're working with objects or primitives regardless of the new autoboxing features. Just my opinion. :-)
|
|
Message #129012
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing in Java is bad
Autoboxing on JVM doesn't have to be complicated, this is Nice http://nice.sourceforge.net/
void main(String[] args){ let c = new ArrayList(); c.add(100); c.add(100); println(c[0] == c[1]);
c.add(10000); c.add(10000); println(c[2] == c[3]); }
Answer: true true
|
|
Message #129014
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
It's only confusing if == is misused. The point is that == is NOT for comparing values of objects (however they were set), and it likely never will be. Of course, but autoboxing is still extremely confusing. For example, <= and >= works fine for Integer objects, but == does not work, ie a <= b && a >= b does not imply a == b. I don't know of any other programming language that works this way, and it goes against all mathematical logic. This is a fair statement IMHO. Autoboxing is confusing, I won't argue that. I'm just saying that the use of == isn't inconsistent and it does exactly what it's specified to do. The >= and <= can be easily overloaded because they don't have any other function or meaning. Unfortunately == is reserved for another purpose. I suppose we could adopt another syntax for equality...like := (pascal asignment) or ===, but that would just be messed up. :-)
Cheers, Clinton
|
|
Message #129025
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
You should know whether you're working with objects or primitives regardless of the new autoboxing features. Just my opinion. :-) Well I'm not sure about the "regardless of..." part because without autoboxing knowing which type you are using is of course a non-issue. However, when you just wrote on one line: i = i + 1, it's pretty distracting to have to think "now am I supposed to say if(i.equals(max)) or if(i==max)?". And it kinda gets even harder when you have a few of these autoboxed things popping around in a longwinding method. 8-)
--J.X.
|
|
Message #129066
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Autoboxing surprises from J2SE 5
It's only confusing if == is misused. Actually the == alone is not the problem. This is something to be teached, I confirm on that. The real problem is that the same operation does not perform consistantly over all the ranges because of behavior change (not because of maths, of course).
It's violating a major criteria for a sound and complete model, something yu'd like to have in a language definition. There have been examples shown for it already.
That's the real issue.
|
|
Message #129102
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
>> I don't know of any other programming language that works this way, and it goes against all mathematical logic. <<
Mathematical logic only applies when you're dealing with numbers. Once you autobox them, they're not numbers, they're objects ... so maths logic doesn't apply.
If Java starts boxing and unboxing each time it encounters something like this:
(x * 2 + 6 + y) == (Y + 3 * 8 + t)
then we could be in for a bit of a wait.
And that's assuming that the compiler can work out whether you are testing values, or trying to decide if you're looking at the sanme object.
Autoboxing is just a bit of syntactic sugar to help with sticking numbers into collections. Folk seem to think that Sun was trying to replace primitives with objects. This is not the case.
|
|
Message #129124
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
Mathematical logic only applies when you're dealing with numbers. Once you autobox them, they're not numbers, they're objects ... so maths logic doesn't apply. I guess in this case most of us are having problem not with "maths logic doesn't apply"(we wouldn't), but with "sometimes it does, sometimes it doesn't". ;-)
|
|
Message #129151
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
So what's the improvement with autoboxing
Ok If I'm not missing anything, Autoboxing just work to save us time typing: Integer myInterger= 2+2; instead of int i=2+2; Integer myInteger= new Integer(i); because after that I shouldn't compare myInteger with ==, => or <= because they're objects and I should use equals() method, right? (like I have to do with Java 1.4) ... so what?? for learning/teaching purposes.. ok you got something more to study/teach but for practical purpouses...What kind of improvement is this? I preffer to type a few caracters more and have a clearer and more consistent language. Java 1.5 save us to work with the XML descriptor storming but I would like to see that the changes bring some improvement (that's the reason of the new versions)
|
|
Message #129255
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
>> I guess in this case most of us are having problem not with "maths logic doesn't apply"(we wouldn't), but with "sometimes it does, sometimes it doesn't". ;-) <<
I think the rules are pretty consistent; doesn't look any different to the object/primitive gotchas we've had all along.
The problem I have with it, is that for the sake of a bit less typing, Sun have introduced a whole new set of 'gotchas'.
Yeah, it was a pain having to box/unbox stuff, but at least folk knew what was going on.
|
|
Message #129256
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
It's confusing
The problem I have with it, is that for the sake of a bit less typing, Sun have introduced a whole new set of 'gotchas'.
Sorry. Badly worded.
Sun haven't introduced more 'gotchas'; they've introduced a dozen more places to watch out for the existing ones.
... which is just as bad really.
|
|
Message #135043
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
How about a coding convention rather than an argument
Java has always be strongly typed and that a good thing but to make code ledgible you need to avoid creating a class called "string".
What Java developers need, to make auto boxing convenient, is a good nameing convention.
For example creating an Integer called i IS arguable confusing when you later test if(i==x)
The solution is to not create the variable i. "i" is traditionally a primative int, If it is used to represent anything else it is the variable name that is confusing not the language
Create and Integer called iBox or iObject Anything with a lowercase start and an uppercase somewhere in it is immediately more obvious to me.
Preprending "obj" is another option that has been around in some circles for a while.
|
|
Message #150728
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Was the problem with autoboxing of 128 fixed in jdk 5.0 final?
After reviewing all of these warnings, I tried the "128" test in JDK 5.0 final. It doesn't appear to demonstrate what I'm reading here. Was this oddity fixed after these tests were run?
I'm speaking specifically of tests like the following. As described in these notes, the first test should have failed, unless I'm misunderstanding something.
Integer num0 = 128; Integer num1 = 128;
// The two objects are both equal to 128 assertTrue((num0 == 128) && (num1 == 128)); // But they are not equal to each other assertTrue(num0 != num1); // true: relational ops unbox both sides assertTrue((num0 <= num1) && (num0 >= num1));
|
|
Message #176327
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Should you teach arrays?
The collection classes have a far richer interface so one might consider eliminating arrays from the course material. When combined with autoboxing, arrays are entirely optional.
I say "one might consider" but I certainly would never consider that. There are important reasons why primitives exist in the first place and performance is still an extremely important aspect of commercial quality software. It's also important insofar as 99.99% of the software out there uses primitives in Java and almost every other commercially viable programming language.
|
|
Message #176504
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
For clarity
I've seen a lot of posts in this thread about what is happening on ==
It's simple:
When we do Integer i = 127; autoboxing turns this into: Integer i = Integer.valueOf( 127 );
Go look at the implementation of Integer.valueOf(), and you'll find: public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset]; } return new Integer(i); }
If the int value is between -128 and 127, it will return a cached Integer value. This way we avoid creating many duplicate Integer objects for those common values. It save's on memory and improves performance.
And, of course, it does mean that Integer i = 127 will always return the same Integer instance.
|
|
Message #260368
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Integer constant pool
From one of the comments: Integer j1 = 127; Integer j2 = 127; System.out.println( j1==j2); //Works!!!
Integer k1 = 128; Integer k2 = 128; System.out.println( k1==k2); //Doesn't Work!!!
Integer w1 = -128; Integer w2 = -128; System.out.println( w1==w2); //Works!!!
Integer m1 = -129; Integer m2 = -129; System.out.println( m1==m2); //Doesn't Work!!! This is nuts and pretty much unacceptable.
This is because Integer constant pool is maintained for integers between -128 to 127. So there a reference comparison is done and it passes. In 128, -129, the references have a different bit pattern..so the == check fails! Hope that helps!
|
|
Message #271027
Post reply
Post reply
Post reply
Go to top
Go to top
Go to top
|
 |
Filling up the left details to the previous two posts
The above two pretty much cleared the Surprise. This message is just added to help understanding better or completely. ------------------------- For message "For clarity", Integer class's static method valueOf(int i) API can explain why this method is used instead of constructor Integer(int i). And the "caching frequently requested values" is done by the constant pool.
From Sun's API of Java 6.
valueOf
public static Integer valueOf(int i)
Returns a Integer instance representing the specified int value. If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values.
Parameters: i - an int value. Returns: a Integer instance representing i. Since: 1.5
-------------------------------------- for message "Integer constant pool"
I quoted some here and add comments to it.
"This is because Integer constant pool is maintained for integers between -128 to 127. So there a reference comparison is done and it passes. In 128, -129, the references have a different bit pattern..so the == check fails! Hope that helps! "
Not only Integer, if replacing the code with Byte(only take values from -128 to 127 anyway), Short, and Long (an L at the end of number for example 127L), it will have similar behavior. Furthermore, the bit patterns probably remain the same as long as the value is valid.
For any number in the range of -128 to 127, it is like the String literal constant pool, using Integer.valueOf(int i) will create just one "integer constant" object corresponding to "i" and the object will be put in the pool, and later same calls will point to the same object. That's why == returns true. This corresponding to the "caching frequently requested values" implementation in the API Integer.valueOf(int i).
For any number outside the range, which won't be put in that pool (which must has limited size here to how just proper number of commonly used "i"s), so a brand new object will be created each time. So the reference variables on both side of == will refer to different objects now. Therefore the return result is false.
overall "==" mainly and only cares the values on two sides.
|
|
 |
New content on TheServerSide.comNew content on TheServerSide.comNew content on TheServerSide.com |
 |
 |
Reza Rahman explores the features of the proposed JSR 299, Contexts and Dependency Injection for Java EE (CDI). When approved, it promises to be a key feature of Java EE 6.
(November 2, Article)
SAML is an XML-based standard for exchanging authentication and authorization data between security domains. The single most important problem that SAML was created to solve is the Web browser Single Sign-On problem. Many organizations are debating whether to stay with version 1.1 or move to 2.0. This article makes observations about both options.
(September 28, Article)
Joe Ottinger takes a look at how people learn, and applies it to the practice of programming. He notes that understanding how people learn is an essential part of working in a programming team.
(September 22, Article)
Stephen Maryka gave us an article about the Asynchronous Web and posed a number of questions that get examined like an approach to delivering Asynchronous Web capabilities through extensions to existing Java EE technologies.
(July 14, Article)
JavaServer Faces Flex goal is to provide users capability in creating standard Flex components, part of flexSDK which is open sourced through MPL license, as normal JSF components. This article by Ji Hoon Kim will provide an overview of creating a simple multilingual JSF page consisting of JSF Flex tags.
(June 29, Article)
In this session Jeff explores the key characteristics of successful SOA projects. He covers some of the patterns, and anti-patterns, tool sets, and strategies that he himself learned the hard way. Last, he provides a strategy and blueprint for achieving a high likelihood of success in your SOA project.
(June 23, Tech Talk)
Ari Zilka, CTO of Terracotta, Inc., talks about the new features in Terracotta 3.1, announced during JavaOne and available now.
(June 15, Tech Talk)
In this Tech Talk, Josh Long explores an integration challenge using Spring Integration and walks through the implementation, employing and expanding on the basic patterns of Enterprise Application Integration to tie together components into a function integration solution, and then demonstrates how Spring Integration helps address the integration requirements.
(June 15, Tech Talk)
In this Tech Talk, David Geary teaches you: The basics of Google Web Toolkit; How to implement Ajax-enabled applications in Java; Internationalization; Hooking into the browser history mechanism; Remote procedure calls.
(June 4, Tech Talk)
Jon Kern discusses the best architecture/technical solutions and ensure that they are repeated by all developers. By tackling the architecture up-front in a serial manner, subsequent parallel development will be much more manageable and predictable.
(May 28, Tech Talk)
This keynote describes the frustrations of modern knowledge workers in their quest to actually get some work done, and solutions for how to guard yourself against all those distractions. Neal Ford talks about environments, coding, acceleration, automation, and avoiding repetition as ways to defeat the misguided attempts to sap your ability to produce good work.
(May 26, Tech Talk)
Gil demonstrates how new, aggressive uses of already abundant compute capacity by common applications offer competitive value for application designers.
(May 21, Tech Talk)
Chris Keene introduces WaveMaker as a new way to automate the ability to generate Hibernate classes in order to more quickly bring OR mapping into an application.
(May 19, Article)
In this session Nati Shalom demonstrates how to take a standard Java EE web application and scale it out or down dynamically without changes to the application code. Seeing as most web applications are over-provisioned to meet infrequent peak loads, this is a dramatic change because it enables growing your application as needed, when needed, without paying for unutilized resources.
(May 19, Tech Talk)
Mastering EJB was one of the original and most influential EJB books in the industry. Mastering EJB III now returns with two new expert co-authors, updated for EJB 2.1 and 30% new chapters including security, integration, best practices, open source, and more.
(Book PDF Download)
The Application Server Matrix is a detailed listing of J2EE vendors and their application server products, with information on latest version numbers, J2EE spec support and licensing, pricing, platform support, and links to product downloads and reviews.
(Application Server Comparison Matrix)
|
|