• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Tim Cooke
  • Ron McLeod
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Junilu Lacar
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Stephan van Hulst
  • Peter Rooke
  • Mikalai Zaikin
Bartenders:
  • Himai Minh

Autoboxing doubt

 
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi

I am trying out the following code snippet:



It gives the output :

different objects
meaningfully equivalent

while if I change the value of i1 and i2 to 10, I get the output:

same object
meaningfully equivalent

I understood the i1.equals(i2) check working in both cases. But why is there a different outcome for the check of (i1==i2) in two cases where only difference being the values of i1 and i2 have been changed? They are still equal though. Aren't they? For 1000, i1!=i2 and for 10 i1==i2. What is going on here? Also, i1==i2 returns true ONLY till 127. 128 onwards i1!=i2 is true. Why this sort of peculiar behavior?
 
Ranch Hand
Posts: 305
Tomcat Server Notepad Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

two instances of the following wrapper objects will always be = = when their primitive values are the same:

Boolean

Byte

Character from \u0000 to \u007f (7f is 127 in decimal)

Short and Integer from -128 to 127

 
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The behavior you are seeing, Mansukhdeep , is from Section 5.1.7 of the Java language specification. It adds this oblique explanation:

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.



Note that last bit, which says you can't rely on any given range of numbers to be wrapped into objects that do or do not equate (other than the minimum ranges the spec requires will equate). Apparently, this is an optimization in contemplation of the notion that most numbers are in those ranges. That is, you tend to use the number "1" a lot more often than the number, "8,345,886," so there's a performance gain in having just one "1" stored in an Integer to represent every single instance of an Integer object that wraps a "1." Or so it seems.

This may seem peculiar, as you say. For what it is worth, I have grudgingly come to realize that most of the features of Java that, at first, seem kind of nutty to me, ultimately prove themselves to be the product of decisions made by people who actually knew what they were doing. (A jaw-dropping exception, of course, is the omission of unsigned data types, which I am told will not be appearing in any version of the language during my current incarnation.)

I tend to take this particular aspect of the language as an indication that testing objects for equality with == is typically not what I want to do, but your mileage may vary.
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stevens Miller wrote:The behavior you are seeing, Mansukhdeep , is from Section 5.1.7 of the Java language specification. It adds this oblique explanation:

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.



Note that last bit, which says you can't rely on any given range of numbers to be wrapped into objects that do or do not equate (other than the minimum ranges the spec requires will equate). Apparently, this is an optimization in contemplation of the notion that most numbers are in those ranges. That is, you tend to use the number "1" a lot more often than the number, "8,345,886," so there's a performance gain in having just one "1" stored in an Integer to represent every single instance of an Integer object that wraps a "1." Or so it seems.

This may seem peculiar, as you say. For what it is worth, I have grudgingly come to realize that most of the features of Java that, at first, seem kind of nutty to me, ultimately prove themselves to be the product of decisions made by people who actually knew what they were doing. (A jaw-dropping exception, of course, is the omission of unsigned data types, which I am told will not be appearing in any version of the language during my current incarnation.)

I tend to take this particular aspect of the language as an indication that testing objects for equality with == is typically not what I want to do, but your mileage may vary.



Hmm.. Off the record, what is meant by unsigned data types?
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

meeta gaur wrote:two instances of the following wrapper objects will always be = = when their primitive values are the same:
Boolean
Byte
Character from \u0000 to \u007f (7f is 127 in decimal)
Short and Integer from -128 to 127


That is NOT true unless autoboxing or valueOf() was used to create the wrapper objects in question.

Winston
 
Stevens Miller
Bartender
Posts: 1464
32
Netbeans IDE C++ Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mansukhdeep Thind wrote:Hmm.. Off the record, what is meant by unsigned data types?


No need to go off the record. An unsigned data type is, in the most general sense, any data type that lacks a sign. As a more practical matter, it is typically an integer data type that stores values from zero to some maximum positive value, almost always reflective of the maximum value that can be stored in a base-two number of eight, sixteen, thirty-two, or sixty-four digits, because these are the natural storage limits of machine words of one, two, four, and eight bytes.

An unsigned byte, for example, if it existed in Java, would stored every value on the range [0, 255]. An unsigned short would cover the range [0, 65535], and so on.

A lot of the work I do involves images, which are very commonly represented as rectangular arrays of pixels, with each pixel represented numerically as three unsigned bytes, one each for red, green, and blue, with 0 indicating least amount of each color, and 255 representing the greatest amount of each color. Java has some great support for manipulating images, but if you want to operate on those pixel values, you either have to store them in some larger primitive (often requiring that you cope with negative values as you do so, unless you have some tricky way of copying the bytes as data, rather than as numbers, if that distinction means anything to you), or else you have to apply some tedious tests to your math operations to find out if the results wrapped around from below 128 to above 127 (and, hence, in Java, became negative).

I read an article about a year ago that says the early language designers felt that programmers didn't really understand unsigned integral primitives. As the former head of the three-dimensional commercial production department at a computer graphics lab whose programmers include many who have gone on to work at places like Pixar and LucasFilm, I can tell you that view is rather deeply flawed. However (and someone with better knowledge of the JVM should chime in here), I have heard that adding unsigned types to Java would be a major overhaul, owing for some reason to the nature of the JVM. That last part may be a false legend, and, indeed, the first bit (about us dumb ol' C programmuhs not bein' able to handle, uhhhh, unsigned numbahs) may be baldersdash as well. What is absolute, hard, undeniable fact, however, is that Java's lack of unsigned integral primitives is a major pain in my backside.
 
meeta gaur
Ranch Hand
Posts: 305
Tomcat Server Notepad Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:

meeta gaur wrote:two instances of the following wrapper objects will always be = = when their primitive values are the same:
Boolean
Byte
Character from \u0000 to \u007f (7f is 127 in decimal)
Short and Integer from -128 to 127


That is NOT true unless autoboxing or valueOf() was used to create the wrapper objects in question.

Winston



Yea, we're discussing here wrapper classes.

true
false
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

meeta gaur wrote:Yea, we're discussing here wrapper classes.


That doesn't alter the fact that, without qualification, your statement is wrong:
returns false; and the only factory method that is documented to return a cached value is valueOf(int).

That doesn't mean that others, such as parsetInt() or decode(), don't; simply that you can't rely on it.

Indeed, valueOf(String) specifically says that it:
"returns an Integer object equal to the value of: new Integer(Integer.parseInt(s))"

Winston
 
Mansukhdeep Thind
Ranch Hand
Posts: 1164
Eclipse IDE Firefox Browser Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stevens Miller wrote:

Mansukhdeep Thind wrote:Hmm.. Off the record, what is meant by unsigned data types?


No need to go off the record. An unsigned data type is, in the most general sense, any data type that lacks a sign. As a more practical matter, it is typically an integer data type that stores values from zero to some maximum positive value, almost always reflective of the maximum value that can be stored in a base-two number of eight, sixteen, thirty-two, or sixty-four digits, because these are the natural storage limits of machine words of one, two, four, and eight bytes.

An unsigned byte, for example, if it existed in Java, would stored every value on the range [0, 255]. An unsigned short would cover the range [0, 65535], and so on.

A lot of the work I do involves images, which are very commonly represented as rectangular arrays of pixels, with each pixel represented numerically as three unsigned bytes, one each for red, green, and blue, with 0 indicating least amount of each color, and 255 representing the greatest amount of each color. Java has some great support for manipulating images, but if you want to operate on those pixel values, you either have to store them in some larger primitive (often requiring that you cope with negative values as you do so, unless you have some tricky way of copying the bytes as data, rather than as numbers, if that distinction means anything to you), or else you have to apply some tedious tests to your math operations to find out if the results wrapped around from below 128 to above 127 (and, hence, in Java, became negative).

I read an article about a year ago that says the early language designers felt that programmers didn't really understand unsigned integral primitives. As the former head of the three-dimensional commercial production department at a computer graphics lab whose programmers include many who have gone on to work at places like Pixar and LucasFilm, I can tell you that view is rather deeply flawed. However (and someone with better knowledge of the JVM should chime in here), I have heard that adding unsigned types to Java would be a major overhaul, owing for some reason to the nature of the JVM. That last part may be a false legend, and, indeed, the first bit (about us dumb ol' C programmuhs not bein' able to handle, uhhhh, unsigned numbahs) may be baldersdash as well. What is absolute, hard, undeniable fact, however, is that Java's lack of unsigned integral primitives is a major pain in my backside.



Looks like you are certainly having a hard time sir. Thank you for your answer.
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stevens Miller wrote:What is absolute, hard, undeniable fact, however, is that Java's lack of unsigned integral primitives is a major pain in my backside.


Actually, you do: - char - and it works just as you'd expect an unsigned short to, except for display. For example:prints out
65345
65025
The problem is that without those final casts, it attempts to print it out as a character.

I suspect there's also a lot of promotion to int going on behind the scenes; but that would be the case for any smaller primitive.

Winston

 
Greenhorn
Posts: 24
Postgres Database VI Editor Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Here is something interesting related to this discussion. If you use the new operator, the code behaves like you expect with the output being "i3 != i4"; however, if you just assign with the = operator, the output is "i3 == i4".
 
Ranch Hand
Posts: 228
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Go forward and read this link Cached Objects

thanks.
 
Marshal
Posts: 77891
373
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Terry Tucker wrote: . . . If you use the new operator, the code behaves like you expect with the output being "i3 != i4"; however, if you just assign with the = operator, the output is "i3 == i4".

You are not assigning 10 there. You are boxing an int into an Integer object. It is equivalent to assigning i3 to Integer.valueOf(10);
The reason you get true from the == operator has already been explained in this thread. This thread also explains why such behaviour is unpredictable and unreliable; you should always avoid the == operator.
 
Campbell Ritchie
Marshal
Posts: 77891
373
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ishan Pandya wrote:Go forward and read this link Cached Objects

thanks.

I have changed that link because it didn’t say that the cache is not a fixed size.
 
Ishan Pandya
Ranch Hand
Posts: 228
Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thaks Ritchie i too will have a look at that link.
 
Campbell Ritchie
Marshal
Posts: 77891
373
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It’s really interesting … except the bit I wrote.
And, “you’re welcome
 
Campbell Ritchie
Marshal
Posts: 77891
373
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Stevens Miller,
Your post was moved to a new topic.
 
Campbell Ritchie
Marshal
Posts: 77891
373
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This thread continues on the Java in General forum. I moved it because it seemed to change subject halfway through.
 
joke time: What is brown and sticky? ... ... ... A stick! Use it to beat this tiny ad!
Master Gardener Program
https://coderanch.com/t/771761/Master-Gardener-Program
reply
    Bookmark Topic Watch Topic
  • New Topic