Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Cloud/Virtualization forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

changing a 'final String'

 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Simple question really, can you change a String that is set to 'final'?
I thought the whole point of a final was that it was just that, but I was asked if you could change a final and when I said no, the person asking implied you could.
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can't. Since String is immutable, once you assign a String to a final variable, that variable will always contain the exact same value. Well ok, with reflection you can change the String's internals, but that's cheating.

Did that person also tell you why / how you can change the value of a final reference?
 
Campbell Ritchie
Sheriff
Posts: 48445
56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If your final reference points to a reference type which is mutable, you can use the values to alter the state of that object.But, as you will see if you un-comment that line 12, you can assign a final reference once and once only.
 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:You can't. Since String is immutable, once you assign a String to a final variable, that variable will always contain the exact same value. Well ok, with reflection you can change the String's internals, but that's cheating.

Did that person also tell you why / how you can change the value of a final reference?


No, it was an interview question.
They didn't actually say you could in those exact words, they said

"So you're saying that if I had a String value that was final I wouldn't be able to change it? So what if I had a String XYZ with the value 'hello' and I wanted to be able to change it to 'goodbye', how would I do that then?"

My answer was - You can't it's final.

But his response implied you could.

PS: Care to enhance on the reflection bit, sounds interesting.
 
Henry Wong
author
Marshal
Pie
Posts: 20902
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
PS: Care to enhance on the reflection bit, sounds interesting.


Basically, you can do something like this...



Henry
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I actually meant changing the internal char[] of a String:
As you can see, s2 changes as well because it shares the char[] with its originating string. Even "better", if you combine this with Henry's code you change source and target too, because they too share the same char[]. Well, target does only after Henry's code.


Henry, I have one question about your code. How can we reassign the private final fields value, offset and count of String? Calling setAccessible(true) should not prevent the overwriting of final fields, or should it?


Edit: I just tried, and in Java 1.4 this is indeed not possible. In Java 6 it is however, but only if the final fields are not static.
Strangely enough, in Java 1.4 the String fields weren't even final...
 
Kevin P Smith
Ranch Hand
Posts: 362
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Edit: I just tried, and in Java 1.4 this is indeed not possible. In Java 6 it is however, but only if the final fields are not static.
Strangely enough, in Java 1.4 the String fields weren't even final...


Nice to see Sun are sticking with consistency, makes it all the more easier to keep up with the constant updates to Java!
 
Henry Wong
author
Marshal
Pie
Posts: 20902
76
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Keith Seller wrote:Nice to see Sun are sticking with consistency, makes it all the more easier to keep up with the constant updates to Java!


To be fair, if you are going to use reflection, you are knee deep in implementation details -- and should assume that you are no longer protected with API backward compatibility.

Henry
 
Rob Spoor
Sheriff
Pie
Posts: 20495
54
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Keith Seller wrote:
Edit: I just tried, and in Java 1.4 this is indeed not possible. In Java 6 it is however, but only if the final fields are not static.
Strangely enough, in Java 1.4 the String fields weren't even final...


Nice to see Sun are sticking with consistency, makes it all the more easier to keep up with the constant updates to Java!

Well they're not breaking existing code if you upgrade. At least not with this feature. You can still modify Strings using reflection (but don't! EVER!), but you can now also modify fields that were already final.
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15207
36
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, this question is actually more subtle that it seems at first sight.

  • If you have a variable that's final, you can't change the value of the variable - you can't make it refer to another object.
  • But you still can change the content of the object that the final variable refers to.
  • But if the object is immutable (and String is immutable), then you can't.
  • But you can cheat by digging into the object via reflection. (Note, never do that in a real-world application, because there are good reasons why String is immutable!).

  •  
    Mark Vedder
    Ranch Hand
    Posts: 624
    IntelliJ IDE Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It's very possible that the interviewer forgot about String's immutably when asking his question. Everyone -- most books, code samples, forum posts, tutorials, quizzes, interview questions, etc. -- always use Strings as their example object type when making points. But a String's immutability -- and how the JVM's manages Strings -- can throw a wrinkle in an otherwise clear cut answer or point. Especially when references are involved. That may be the case here. The interviewer might have wanted to see if you understood that a reference was final, but that the (mutable) object it references could be altered. But by using a String as the example object, he unintentionally negated his own question. Just a hypothesis, but one I would believe to be likely.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic