wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Final object's value could be changed? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Final object Watch "Final object New topic
Author

Final object's value could be changed?

Larry Olson
Ranch Hand

Joined: Feb 03, 2009
Posts: 142
Hi,

A final object's value could be changed, right? i.e. not the reference itself could be re-assigned, but the contents of the object the reference is pointing to could be changed.
But how does this work out in the case of wrapper objects. For example given,

final Integer x = 5;

How could I change the value of x?

Thanks.



Michael Angstadt
Ranch Hand

Joined: Jun 17, 2009
Posts: 273

Hi Larry,

When you can change the contents of an object, the object is mutable. The ArrayList class is mutable because you can add and remove elements from it. Wrapper objects, however, are immutable, meaning you cannot alter the contents of the object. The String class is also immutable. Methods like substring() and replace() return a new String instance, leaving the original one untouched. So because wrapper objects are immutable, there's no way to change the value of an Integer object. And, in your case, since the variable is final, you can't even reassign the reference.


SCJP 6 || SCWCD 5
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18532
    
  40

Immutable objects are... immutable. The objects value does not change.

[EDIT: beaten again. And with a much more detailed answer]

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Larry Olson
Ranch Hand

Joined: Feb 03, 2009
Posts: 142
Thanks for the detailed explanation. That helps. I just have one more questoin. In that case i.e. wrapper objects being immutable and particular final wrapper objects being very much so, why aren't they being allowed inside switch statements as case values?

i.e.

(1)
final Integer x = 5;
case x: //isn't allowed

even though logically x is a constant and it is immutable

whereas

(2)
final int x = 5;
case x: //is allowed

When I compile (1), the compiler gives the following error:
"constant expression required", even though as you very well explained "final Integer x = 5"; is immutable, which means it is a constant. But still the compiler insists that it requires a constant expression. What gives? Please, I don't want to hear that the JLS is the reason.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18532
    
  40

Larry Olson wrote:Please, I don't want to hear that the JLS is the reason.


Then ignore this answer.... When the compiler is complaining about it not being a constant. It is referring to a compile time constant.

And the definition of compile time constant is very specific. Wrapper objects are not candidates of being compile time constants. The operations needed to box and unbox the values are not allowed of compile time constants.

Henry
Michael Angstadt
Ranch Hand

Joined: Jun 17, 2009
Posts: 273

I think this is because what switch cases do is check for equality using ==. So this switch statement:



is equivalent to:



This doesn't jive well with objects, which use the equals() method to check for equality. For example:



(== works when Integers are within a specific range, due to the way Java interns Number objects, but for larger numbers it does not work)

Also, there's no way for Java to know if an object is immutable or not.

Simon Boyle
Greenhorn

Joined: May 26, 2010
Posts: 2
Careful! I think I remember seeing somewhere that Integer wrappers < 128 are likely to return true when using an == comparison, anyhting else is likely to return false.

A quick test reveals this:

public class eq {
public static void main(String... args) {
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;

System.out.println(i1 == i2);
System.out.println(i3 == i4);
}
}

prints:

true
false

Take care if you're going to do this (I wouldn't recommend it...). I didn't get a question like this on my SCJP but that's not to say there aren't any!

Simon.

Yogesh Gnanapraksam
Ranch Hand

Joined: Dec 17, 2009
Posts: 133
== works when Integers are within a specific range, due to the way Java interns Number objects, but for larger numbers it does not work)


I do not understand .I remember something related to this context was discussed earlier here but I am not able to find it.

Can somebody please explain..

Michael Angstadt
Ranch Hand

Joined: Jun 17, 2009
Posts: 273

Like Simon alluded to, the values from -128 to 127 are interned.


This also applies to Bytes, Shorts, and Longs.
wbrian radley
Greenhorn

Joined: Apr 03, 2008
Posts: 22
addendum: be very careful with interned values as they apply only in one very specific case:
(and, yes, the correct boolean values are being printed even tho' the flag is s)


Sahil Kapoor
Ranch Hand

Joined: Sep 12, 2009
Posts: 316
Please explain what is the Logic going on !!!


SCJP 6.0 96%

(Connecting the Dots ....)
Yogesh Gnanapraksam
Ranch Hand

Joined: Dec 17, 2009
Posts: 133
Sahil,
This is the same logic that is implemented by the intern() method in String Class.
You can look here http://www.coderanch.com/t/488922/java/java/new-keyword-objects-Java#2198278 for details.
As per the discussion here the same applies for Integers,Short and Byte.
But I do not understand why intern is not done for numbers greater than 127.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18532
    
  40

Yogesh Gnanapraksam wrote:
I remember something related to this context was discussed earlier here but I am not able to find it.


Just do a search on "integer cache". This topic comes up often.

Henry
Yogesh Gnanapraksam
Ranch Hand

Joined: Dec 17, 2009
Posts: 133
Thanks Henry.
I got an understanding of this logic now.
JSL spec
Martin Vanyavchich
Ranch Hand

Joined: Sep 16, 2008
Posts: 241
As for switch statements and wrapper classes ... keep in mind that an Integer object can point to null. How would you squeeze that into a switch statement


SCJP 6, OCMJD 6, OCPJWSD 6
I no good English.
 
Consider Paul's rocket mass heater.
 
subject: Final object's value could be changed?
 
Similar Threads
final variable related problem.
final modifier
Passing by value vs. reference
final Integer reference in case statement
Final primiives