I recently encountered a situation in a Java project where I wrote a block like this:
String user = System.getProperty("user.home").toUpperCase();
user = user.substring(user.lastIndexOf(File.separator) + 1);
final String path1 = "C:\\first\\path";
final String path2 = "C:\\second\\path";
final String uniquePath = "C:\\users\\" + user + "\\unique\\path";
I'm just getting into practice of marking variables as final
for style, but not sure how to handle this type of example. As I understand it, final
is often used not just to prevent a value from being changed, but to indicate to the reader right off the bat that this variable is immutable. In this example, someone sees that path1
, path2
, and uniquePath
are not going to change, and that fundamentally changes the way they think about those variables.
My concern is that, in the above example, the paths are clearly final
, and user
is clearly not. It's not too hard (I think) to work out that user
probably isn't going to be manipulated, and the only reason it isn't also final
is because it can't be gotten in one expression. However, if I saw this code, it would be really difficult for me to mentally group user
with the paths. The coder obviously wanted to point out which variables were final
, and they didn't mark user
.
It seems then that something like this would make things more clear:
String temp = System.getProperty("user.home").toUpperCase();
temp = temp.substring(temp.lastIndexOf(File.separator) + 1);
final String user = temp;
final String path1 = "C:\\first\\path";
final String path2 = "C:\\second\\path";
final String uniquePath = "C:\\users\\" + user + "\\unique\\path";
But I'm not sure if this is worth the extra space and variable needed.
Is there a consensus on which of these approaches is a better practice? Is there a better option I've not considered?
temp
variable and the code it's using to a method and then dofinal String user = yourNewFunction()
? This doesn't exactly solve your questions but definitely is a way to do this too. – Mibac Jul 13 '17 at 20:03final
on everything that doesn't actually change deeply misguided. If it's not immediately obvious in a method what changes and what doesn't, then the method is too long to understand, and adding further verbiage doesn't help. Things would be different if constness was the default and Java had an explicitvar
keyword for non-constant things, but unfortunately it's far too late to turn things around on this point. – Kilian Foth Jul 13 '17 at 21:03final
should be used for variables that are very important that they don't change, not variables that are "by the way this doesn't change". e.g., in your code, ifpath1
changed after the creation ofuniquePath
, would anybody care? – user949300 Jul 14 '17 at 3:34final
doesn't mean immutable. It's very important to understand the distinction. Immutable means there is no determinable change in state after the instance has been created.final
just prevents the variable from being reassigned. For those of us that learnedconst
in C++, I'll admit such a concept would have been nice in Java (const
modifier meant only otherconst
methods could be called, andconst
methods could not change state of instance, so essentially forcing an instance to be immutable on the fly). – Neil Jul 14 '17 at 10:16