0

In SCJP book i get a point by Kathy Sierra that their is no final object in java. There are only final reference variable in java.

But i think objects of string class are final. As once initialized their state can not change.

Now question is that the objects of string class are final or not. If they are not than how the objects of string class are immutable.

Thanks

Deepak Agrawal
  • 1,301
  • 5
  • 19
  • 43
  • I tkink the point is, that if you have variable `a` of class `A`, you cannot make `a` final (at least not in a way you could in C++ by const), unless class `A` allows it (e.g. it has `makeImutable()` method or something, that will disallow further changes). read more: http://stackoverflow.com/questions/4971286/javas-final-vs-cs-const – kajacx Mar 11 '14 at 22:18

3 Answers3

4

But i think objects of string class are final. As once initialized their state can not change.

No, they're not final in the Java sense. They're immutable, but final relates purely to variables/data members, not objects.

Here's an example:

final String a = "foo";
String b = "bar";

b = "updated bar"; // Compiles and works, `b` (the variable) can be changed
a = "updated foo"; // Won't compile, you're not allowed to change the `a` variable

final is about whether a "variable"'s value can be changed, not about whether the state of an object can be changed.

Here's an example with a final variable referring to a mutable object:

final Map a = new HashMap();

a.add("foo", "bar"); // Works; we're not changing `a`, we're changing the state
                     // of the object `a` refers to

And just to take objects out of it entirely:

final int a = 5;
a = 6; // Won't compile, because we aren't allowed to change `a`
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • but how to change content of "foo" object of string class itself. how "foo" string is maintained immutable. I think it should probably be final. – Deepak Agrawal Mar 11 '14 at 22:21
  • @D.k.Agrawal: *"but how to change content of "foo" object of string class itself."* "Object" (or "instance"), not "class"; and you can't. *"how "foo" string is maintained immutable. I think it should probably be final."* It's immutable because there is no operation available on `String` that changes the state of the object. That has nothing to do with whether a variable referring to the object can be updated to refer to a new object. – T.J. Crowder Mar 11 '14 at 22:23
  • "`final` relates purely to variables/data members, not objects" -- True, but `final` also has another meaning when applied to classes, so it isn't applied *purely* to fields and variables, and `String` is final, although that has nothing to do with why it's immutable. – David Conrad Mar 11 '14 at 22:28
  • 1
    (Actually, you can change a String, through reflection, but doing so is evil.) – David Conrad Mar 11 '14 at 22:29
  • @T.J.Crowder - And it is even more subtle than that, because there is a method that changes the *internal* state of a String; `hashcode` in typical implementations. But we can still say that String is immutable because that state change (hashcode caching) is undetectable using the String's public API. – Stephen C Mar 11 '14 at 22:29
  • 2
    @DavidConrad - Any object can be changed like that. But we don't factor that into discussion of immutability, because using reflection to break abstraction is an area that the JLS says is outside of the Java language. The behaviour is unspecified. (And using `Unsafe` or JNI/JNA calls to do the same thing are too.) – Stephen C Mar 11 '14 at 22:34
  • @StephenC Sure, that's why I put it in parentheses. Including it for completeness, but not suggesting it violates immutability. – David Conrad Mar 11 '14 at 22:44
  • 3
    @DavidConrad - I saw and understood the parentheses. But I suspect that others may not understand the subtlety. (In fact, I recall previous Questions where people have incorrectly argued that the evil reflection back-door makes String mutable!) – Stephen C Mar 11 '14 at 22:53
1

First you have to read this:

http://en.wikipedia.org/wiki/Final_(Java)

Because in Java final keyword can be used in several different context.

String class is immutable, it means that after creation state of this object cannot be changed and is also declared as final which means it can't be subclassed.

Jakub H
  • 2,130
  • 9
  • 16
  • yaaa jakub i already read. how string class objects are immutable. Means what in actual being performed by JVM to keep String objects immutable – Deepak Agrawal Mar 11 '14 at 22:26
0

You would have to post the chapter (please don't, by the way) to fully give the context, but I can distinguish the two concepts further for you.

final is a keyword in java that applies, in your case, to a reference variable. That means that once the object is instantiated, that variable cannot be assigned to a different object, i.e., if you do:

final String[] stringArray = new String[8];

you can never do anything again like this:

stringArray = new String[2];//stringArray is final and cannot be reassigned

This doesn't indicate however that if the contents of stringArray are not able to be changed. You can do:

stringArray[3] = "Hey!";

And it will compile just fine. This shows you that just the reference cannot be reassigned to anything else; we're only talking the reference here.

When they say String is immutable, they are talking about the String constant pool. In the string constant pool there is a collection of strings that have been created in memory that are stored for reuse. If you say, for example:

String tempString1 = "yo";
String tempString2 = "yo";

You only created 1 string object in the string constant pool (a special part of memory where strings go) and assigned it to two different reference variables. If you do:

tempString2 = "hey";
String tempString3 = "yo";

you have only created 1 new object again, "hey", in the string constant pool. tempString1 only changed what it was pointing to, and tempString3 is reusing "yo" that has already been created.

If you do this because you're nuts about Java:

tempString1 = tempString2 + tempString3;
String tempString4 = tempString2 + tempString3;
String tempString5 = tempString2 + tempString3;

You have only created 1 more string "heyyo". "yo" "hey" and "heyyo" are the only strings in the String constant pool.

Any operation you do will not change "hey" and "yo" in the string constant pool, even though you may change output to appear like those strings have changed.

Sandy Simonton
  • 604
  • 5
  • 15