NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Speaking of "bad optimization", a nice (bad) example can be illustrated by the following autoboxing horror:
Integer a = 10, b = 10 ;
Integer c = 129, d = 129 ;
System.out.println( a == 10 ) ; // A
System.out.println( a == b ) ; // B
System.out.println( c == 129 ) ; // C
System.out.println( c == d ) ; // D
> true
> true
> true
> false
At first I was puzzled, then looking at the Integer source code, I found that it was due to an (undocumented) "optimization": The value between -127 to 127 are cached. This is so bad that I wonder how it got into the Java standard library I understand that the aim here is to avoid creating new objects for small numbers. But Sun engineers should have created a new class for that (such as Javolution
Index
class), instead of doing some bastard optimization leading to a terrible autoboxing behavior.
Well I'm not sure that you would use the '==' operator to test the numeric values, but it is still an inexcusable botch. The behaviour should be the same, no matter what the numbers are.
Set your IDE to flag up any comparisons of objects using == as a warning or an error. It's been known for years that == on objects is dubious, and we can cope with it. For example, "hello"=="hello" but "hello"!=new String("hello").
And yes, folks, calling the String(String) constructor is pointless except as a demonstration.
>
Don't use wrapper classes to do any math.
Is
> that rule is too difficult to follow? :-)
The problem with autoboxing is that it does the wrapping for you, e.g. you might think you are dealing with
int
but instead you are using an Integer wrapper.
Jean-Marie Dautelle - Marlboro, MA
-- Javolution: Everything should be made as simple as possible...
-- JScience: But not simpler!
By the way, Jean-Marie, did you actually come across this in real code? I've never seen a question on it posed by somebody who'd actually seen problems because of it, only by people seeing someone else blogging about it (surely the blog trail must lead back to somewhere though).
I think most of us can recognise an Integer reference.
> I found that it was due to an (undocumented)
> "optimization": The value between -127 to 127 are
> cached. This is so bad that I wonder how it got
> into the Java standard library
I had some code that people under me were writing. They were looking at where they were trying to compare Integers with == and in testing the code worked, and on production it ended up breaking. The fix was to call, intValue() on the interger object to make sure it works, so yes this can happen in real code.
> By the way, Jean-Marie, did you actually come across
> this in real code? I've never seen a question on it
> posed by somebody who'd actually seen problems
> because of it, only by people seeing someone else
> blogging about it (surely the blog trail must lead
> back to somewhere though).
I saw it on dzone and did not believe it. So, I tried it and to my surprise it was correct.
Jean-Marie Dautelle - Marlboro, MA
-- Javolution: Everything should be made as simple as possible...
-- JScience: But not simpler!
> Undocumented, eh? Perhaps it was snuck in to the JDK
> because that behavior is required by the Java
> Language Speciciation, third edition.
> http://java.sun.com/docs/books/jls/third_edition/html > conversions.html#5.1.7
Then it is worst than I thought! We have now a "documented" unexpected behavior which we cannot correct without changing the Java Spec
Reading the spec, another artificial special case has been created for chars between 0 and 0x7F (our non-english speaking friends must be sad that their characters do not benefit from this optimization ).
When some low-level optimization "leaks" to the Java spec then one should start to worry...
Now, I understand what it is not mentioned anywhere in the API (not even in Integer.valueOf(int)). Every Java developer should know by heart the 644 pages of the Java Spec
And by the way, the irony is that this kind of optimization tell us that Sun does not believe that object creation is as fast as they claim it to be ... so funny....
Jean-Marie Dautelle - Marlboro, MA
-- Javolution: Everything should be made as simple as possible...
-- JScience: But not simpler!
> > I found that it was due to an (undocumented)
> > "optimization": The value between -127 to 127 are
> > cached. This is so bad that I wonder how it got
> > into the Java standard library
>
> Undocumented, eh? Perhaps it was snuck in to the JDK
> because that behavior is required by the Java
> Language Speciciation, third edition.
> http://java.sun.com/docs/books/jls/third_edition/html > conversions.html#5.1.7
From the JLS:
> If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
Gack! That's got to be the most C/C++ - like thing I've seen in the JLS.
Yes, it's better to have it documented than not. But it sure seems like it must have been implemented first, and then added to the JLS. I can't picture someone proposing a JLS change with "hey, I've thought of a great language change having to do with equality of autoboxed values between -128 and 127"
Andy Tripp, CTO and Founder Jazillian
- Legacy to 'natural' Java.
There's no guarantee that the objects have unique instances. You shouldn't be comparing objects using ==.
Using the == with one of them being a primitive is asking it to unbox the other one, so a == 10 is ok I think.
I'm in favor of this optimization, we need all the performance we can get.
Who knows what kind of optimizations we'll see in collections. If I stuff an Integer into an array, and what I get out is another Integer, but with the same value, I'm ok with that, I think.
> ... I can't picture
> someone proposing a JLS change with "hey, I've
> thought of a great language change having to do with
> equality of autoboxed values between -128 and 127" :)
Unless they needed material to write a third "Java Puzzlers" book
Jean-Marie Dautelle - Marlboro, MA
-- Javolution: Everything should be made as simple as possible...
-- JScience: But not simpler!
There is a very simple way to prevent this sort of headaches: Never use Autoboxing (and if your IDE allows, have it mark each unitentional usage as an error).
My IDE makes sure that I never use Autoboxing, and I never had the feeling that anything was missing. Autoboxing should have never been introduced (as I have said about 100 times before).
Autoboxing Horror!
At 10:26 AM on Jan 18, 2007, Jean-Marie Dautelle
wrote:
Fresh Jobs for Developers Post a job opportunity
At first I was puzzled, then looking at the Integer source code, I found that it was due to an (undocumented) "optimization": The value between -127 to 127 are cached. This is so bad that I wonder how it got into the Java standard library
I understand that the aim here is to avoid creating new objects for small numbers. But Sun engineers should have created a new class for that (such as Javolution Index class), instead of doing some bastard optimization leading to a terrible autoboxing behavior.
89 replies so far (
Post your own)
Re: Autoboxing Horror!
Well I'm not sure that you would use the '==' operator to test the numeric values, but it is still an inexcusable botch. The behaviour should be the same, no matter what the numbers are.Re: Autoboxing Horror!
Of course here you are not testing the values (10==10) but the objects (a==b).In the case above I would have expeced that a==b be false. That's what Jean-Marie has noticed.
Personally I never use == to compare 2 objects.
Re: Autoboxing Horror!
Don't use wrapper classes to do any math. Is that rule is too difficult to follow?Re: Autoboxing Horror!
Set your IDE to flag up any comparisons of objects using == as a warning or an error. It's been known for years that == on objects is dubious, and we can cope with it. For example, "hello"=="hello" but "hello"!=new String("hello").And yes, folks, calling the String(String) constructor is pointless except as a demonstration.
Re: Autoboxing Horror!
> Don't use wrapper classes to do any math. Is> that rule is too difficult to follow? :-)
The problem with autoboxing is that it does the wrapping for you, e.g. you might think you are dealing with
intbut instead you are using an Integer wrapper.-- Javolution: Everything should be made as simple as possible... -- JScience: But not simpler!
Re: Autoboxing Horror!
By the way, Jean-Marie, did you actually come across this in real code? I've never seen a question on it posed by somebody who'd actually seen problems because of it, only by people seeing someone else blogging about it (surely the blog trail must lead back to somewhere though).I think most of us can recognise an Integer reference.
Re: Autoboxing Horror!
> I found that it was due to an (undocumented)> "optimization": The value between -127 to 127 are
> cached. This is so bad that I wonder how it got
> into the Java standard library
Undocumented, eh? Perhaps it was snuck in to the JDK because that behavior is required by the Java Language Speciciation, third edition. http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7
Re: Autoboxing Horror!
Ricky,I had some code that people under me were writing. They were looking at where they were trying to compare Integers with == and in testing the code worked, and on production it ended up breaking. The fix was to call, intValue() on the interger object to make sure it works, so yes this can happen in real code.
Re: Autoboxing Horror!
> By the way, Jean-Marie, did you actually come across> this in real code? I've never seen a question on it
> posed by somebody who'd actually seen problems
> because of it, only by people seeing someone else
> blogging about it (surely the blog trail must lead
> back to somewhere though).
I saw it on dzone and did not believe it. So, I tried it and to my surprise it was correct.
-- Javolution: Everything should be made as simple as possible... -- JScience: But not simpler!
Re: Autoboxing Horror!
> Undocumented, eh? Perhaps it was snuck in to the JDK> because that behavior is required by the Java
> Language Speciciation, third edition.
> http://java.sun.com/docs/books/jls/third_edition/html
> conversions.html#5.1.7
Then it is worst than I thought! We have now a "documented" unexpected behavior which we cannot correct without changing the Java Spec
Reading the spec, another artificial special case has been created for chars between 0 and 0x7F (our non-english speaking friends must be sad that their characters do not benefit from this optimization
When some low-level optimization "leaks" to the Java spec then one should start to worry...
Now, I understand what it is not mentioned anywhere in the API (not even in Integer.valueOf(int)). Every Java developer should know by heart the 644 pages of the Java Spec
And by the way, the irony is that this kind of optimization tell us that Sun does not believe that object creation is as fast as they claim it to be ... so funny....
-- Javolution: Everything should be made as simple as possible... -- JScience: But not simpler!
Re: Autoboxing Horror!
> > I found that it was due to an (undocumented)> > "optimization": The value between -127 to 127 are
> > cached. This is so bad that I wonder how it got
> > into the Java standard library
>
> Undocumented, eh? Perhaps it was snuck in to the JDK
> because that behavior is required by the Java
> Language Speciciation, third edition.
> http://java.sun.com/docs/books/jls/third_edition/html
> conversions.html#5.1.7
From the JLS:
> If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
Gack! That's got to be the most C/C++ - like thing I've seen in the JLS.
Yes, it's better to have it documented than not. But it sure seems like it must have been implemented first, and then added to the JLS. I can't picture someone proposing a JLS change with "hey, I've thought of a great language change having to do with equality of autoboxed values between -128 and 127"
Re: Autoboxing Horror!
I have to sort of go ahead and disagree here.There's no guarantee that the objects have unique instances. You shouldn't be comparing objects using ==.
Using the == with one of them being a primitive is asking it to unbox the other one, so a == 10 is ok I think.
I'm in favor of this optimization, we need all the performance we can get.
Who knows what kind of optimizations we'll see in collections. If I stuff an Integer into an array, and what I get out is another Integer, but with the same value, I'm ok with that, I think.
Re: Autoboxing Horror!
> ... I can't picture> someone proposing a JLS change with "hey, I've
> thought of a great language change having to do with
> equality of autoboxed values between -128 and 127" :)
Unless they needed material to write a third "Java Puzzlers" book
-- Javolution: Everything should be made as simple as possible... -- JScience: But not simpler!
Re: Autoboxing Horror!
There is a very simple way to prevent this sort of headaches: Never use Autoboxing (and if your IDE allows, have it mark each unitentional usage as an error).My IDE makes sure that I never use Autoboxing, and I never had the feeling that anything was missing. Autoboxing should have never been introduced (as I have said about 100 times before).