I know how the compiler interprets the final keyword in Java, but how should us programmers interpret its meaning? Should it be:
1) This variable cannot be changed (used by inner class for example)
or
2) I'm not planning to change this variable (might have some optimisation benefits for member variables).
I'm asking because I've worked on code where everything is declared final by default (option 2 above) which, in my opinion, devalues the keyword and hides the values that really can't change! Is there still performance benefits in declaring variables final?
Everything being final by default is a good thing. The more you can model your code on immutability, the easier it tends to be to reason about.
Using final is hardly ever about performance in my opinion. It's about making assertions about the rest of the code (nothing changes this variable) which can help a reader to understand the code, and can be checked by the compiler.
EDIT: The above is my view for fields. For local variables (including parameters) I personally only use final when the variable will be used in an anonymous inner class. This is different from fields because:
It's easy to see the whole context of the method - and if it's not, that's a problem in itself.
As it doesn't represent the state of an object (or class) the benefits of immutability don't really apply.
The final keyword should be abandoned, it should be standard in all applicable cases, and the finality should only be revokable with a keyword like
this_variable_will_change_unexpectedly_behind_your_back
This keyword should not get autocompleted by any IDE, and it shoud not be possible to insert it with Ctrl-V.
I wrote a post about this a while ago.
Final helps reading code:
without the use of final everything may be mutable (potential mess)
it forces setting a variable before it can be used (useful in constructors)
By using final you tell the compiler something about your code and it helps you in return.
The 2nd option is a safeguard. It stops you from accidentally changing or reassigning. As such it's useful to provide and you can remove when you decide you want that variable to change.
I can't add much to what Jon has already said, but just for completeness, JLS 17.5.3 says final fields also may lead to optimizations;
If a final field is initialized to a compile-time constant expression (§15.28) in the field declaration, changes to the final field may not be observed, since uses of that final field are replaced at compile time with the value of the constant expression.
I don't understand why you think there's lack of value.
When I see all final variables, it implies that the class is immutable. That's a good thing, because immutable classes are inherently thread safe.
final variables are a good thing generally speaking. Note that it only means that the variable can't be reassigned, but the object it points to can change if it is mutable.
Performance wise, final allows more aggressive compiler optimisations:
the specification allows aggressive optimization of final fields. Within a thread, it is permissible to reorder reads of a final field with those modifications of a final field that do not take place in the constructor.
Declaring every variable as final is not devaluing final keyword. It helps developers in debugging the application to rule out possibility of modification of variables, especially during multi threaded environment of application.
With java 8 release, we have one more concept called "effectively final variable"
local variables referenced from a lambda expression must be final or effectively final
A variable is considered effective final if it is not modified after initialization in the local block. This means you can now use the local variable without final keyword inside an anonymous class or lambda expression, provided they must be effectively final.
If you don't want to declare effective final as final variable, this new feature helps you if you are using lambda expressions/anonymous classes. You can avoid declaration of final keyword for effective final variables. Have a look at this article
Its true that final variable is used so that no one can change the value, it works as constant in java.
Let me give example
I have created one package which can be used by some other person as well, now there are some configurations variable that are need to set in order to run it properly. lets say its login package. So there can be few encryption options like
encryption_method = HASH_ENCRYPTION
OR
encryption_method = SYMMETRIC_ENCRYPTION
instead of passing integer 1, 2, 3 we can define final variable which helps developer in more readable form and ofcource i don't want user to change it so I keep it final, else internal logic may break
Related
As a user newly switching to Java, I have realized that in our project and some other Java projects, final keyword is commonly used and after reading several tutorials and SO threads e.g. Excessive use "final" keyword in Java, I think there is some examples that do not require final keyword. So, here are the points I am confused:
1. Is there any need to use final keyword in method parameters in classes and interfaces? Because
CompanyDTO findByUuid(final UUID uuid);
//or
#Override
public CompanyDTO findByUuid(final UUID uuid) {
//...
}
2. As far as I know, it also good for thread safety, but I need to understand the basic idea on why it is used almost every possible places in Java. Normally it is used for the variables that will not be changed. So, could you please explain the idea of common usage?
Is there any need to use final keyword in method parameters in classes and interfaces?
None. Because the effects of using it are miniscule.
As far as I know, it also good for thread safety
Not at all. A change to a primitive parameter is not visible outside of the method body. On the other hand final doesn't prevent you from invoking a method on a reference type parameter.
In other words: if your method body does something that ends up causing a race condition between different threads, then final doesn't help with that at all.
The absolute only thing that using final for parameters prevents you from doing: re-assigning values to it. So, it can help preventing stupid mistakes. But it almost comes down to pure style. Me for example, I almost never use it, and regard it useless clutter/noise most of the time.
Using final modifier on method parameters doesn't make much sense
since it adds visual clutter to the method declaration without
buying you much. As far as you can make sure that you don't reassign
values to those variables, you are good enough to go without final
modifier on method parameters.
Method parameters lie on the stack, and it is local to that
particular thread as far as that thread doesn't publish it to some
other thread. Since it is not shared between the other threads, no
thread safety issue arises here. However, if the current thread
publishes these arguments, then you are out of luck and the use of
final modifier doesn't give you any thread safety guarantee.
Here's one such a tasteful use of final modifier to write an immutable class which represents a point in our 2-dimensional space.
class Point2D {
private final int x;
private final int y;
Point2D(int x, int y) {
this.x = x;
this.y = y;
}
// Remainder omitted for brevity's sake !
}
Once this class instance is created, you can share it freely with other threads and you don't need to bother synchronizing access to it's state. So, immutable objects give you thread safety for free.
You may read JLS § 17.5 for more details on semantics of final fields.
1. Is there any need to use final keyword in method parameters in classes and interfaces?
It depends on what these methods do.
For example, if they contain lambdas, some rules apply.
See JLS §15.27.2
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
In java8, variables are effectively final if we do not assign them again. So, it means if we are declaring a method and if we don't declare its parameters to be final, then they are effectively final if we don't assign them in the method definition. So, does making the parameters final make any difference in java8?
IMO, the reason to mark a parameter final is to show that you are depending on it being final. This might be the case if you are using the parameter in a lambda expression or an inner class. Marking the parameter final tells the next programmer who comes along (or you a year from now) that there is code that relies on that parameter being final.
No. it isn't effectively final unless you use it inside anonymous function or lambda expression. Not in normal methods, why should it be.
I use final the same way as you. To me it looks superfluous on local variables and method parameters, and it doesn't convey useful extra information.
One important thing is that strive to keep my methods short and clean, each doing a single task. Thus my local variables and parameters have a very limited scope, and are used only for a single purpose. This minimizes the chances of reassigning them inadvertently.
Moreover, as you surely know, final doesn't guarantee that you can't change the value/state of a (nonprimitive) variable. Only that you can't reassign the reference to that object once initialized. In other words, it works seamlessly only with variables of primitive or immutable types. Consider
final String s = "forever";
final int i = 1;
final Map<String, Integer> m = new HashMap<String, Integer>();
s = "never"; // compilation error!
i++; // compilation error!
m.put(s, i); // fine
This means that in many cases it still doesn't make it easier to understand what happens inside the code, and misunderstanding this may in fact cause subtle bugs which are hard to detect
When I'm using lambda expressions or anonymous inner classes, with variables from outer class, I often get the compile time error:
Lamba expressions:
local variables referenced from a lambda expression must be final or effectively final
Inner classes:
local variables referenced from an inner class must be final or effectively final
It means that compiler in Java 8 is able to deduce whether variable is implicitly final or not. Regarding to this question, using final variables instead of non-final sometimes gives a huge positive impact on performance.
My question is: Does compiler in java 8 interpret effectively final variables as final variables and later, in runtime use it as final?
In consequence, does it make the same optimization, as it's doing for the final variables?
Questions about differences between effective final and final (i.e. this) are connected with the reason why it has to be effectively final but doesn't say anything which answers my question.
I would be grateful for any answers.
Does compiler in java 8 interpret effectively final variables as final variables and later, in runtime use it as final?
The answer will be yes in both cases.
The reason for the latter is that the class file format does not provide a way to say whether a local variable is declared as final. Therefore, if the JIT compiler is going to optimize based on finality, the finality must be inferred from what the bytecodes of a method actually do; i.e. effective finality.
"Regarding to this question, using final variables instead of non-final sometimes gives a huge possitive impact on performance."
If I understand correctly the question you linked to, it really has nothing to do with "effectively final". The positive impacts you're referring to are for instance variables (that aren't private); declaring them final can be helpful because it means that the compiler can be sure that no method in a subclass can modify the variable.
"Effectively final" is a concept that applies only to local variables declared inside a method (including parameters). There's no possibility that a local variable in a method could be modified in a subclass.
Using the final keyword on local variables in a method might help with optimization, but a good compiler wouldn't need it. It would be able to tell that a variable doesn't change, and optimize accordingly. In fact, even if the variable isn't final, but the compiler can tell that it doesn't get modified for a certain stretch of code, a good compiler should be able to figure out that it isn't changed during that period, and make optimizations based on that.
In Java when a final field is assigned a constant value compile-time, it usually makes sense declaring it static. It saves overhead according to the relevant PMD rule.
Does it make any sense or difference doing it in GWT regarding the generated Javascript code?
If the variable is assigned when it is declared final, then yes, static makes a certain amount of sense, but there are cases where it should not be static:
public MyClassWithFinal {
private final String finalVar;
public MyClassWithFinal(String name) {
this.finalVar = name;
}
}
Another case: If the instance var is not a string or number constant, but requires running a constructor, that constructor may have side effects each time it is invoked, so running it only once is different than running it multiple times.
That said, GWT will inline/intern constant string values, so if you have multiple String fields all assigned to the same value, GWT will probably detect that and promote them all to static.
public final String constant = "Some Constant that really ought to be static";
GWT will notice that this is never assigned except when declared, and may even remove the field itself.
The best rule is to start with the best (i.e. most readable, most maintainable, most efficient) Java code, and to only break from that in cases where GWT requires something specific. This is not one of those cases: the compiler should perform the same basic optimizations no matter how you write this.
A field marked as final doesn't mean that it is immutable, only that its reference won't point to any other memory chunk. Therefore, it can only make sense to make a field static if it is really immutable, or if it is a primitive.
For instance, it's common to declare lists as final if you want to make sure that they will never point to a different list object, but the list itself can still be filled with data, cleared, filled again, etc. And of course, each object declaring such list does not mandatory want to share it among every instances.
private final List<...> list = new ArrayList<...>();
Final keyword is there to prevent you from doing mistakes, like setting to null a reference that should never change.
I've just come across some code that's confusing me slightly; there are really 2 variations that I'd like to clarify.
Example 1:
public String getFilepath(){
final File file = new File(this.folder, this.filename);
return file.getAbsolutePath();
}
What would be the purpose of declaring file "final"? Since Java primitives are passed by value, and getAbsolutePath() is just returning a String, the variable won't be final on the other side (calling method), will it? And since the file variable only exists within the scope of these 2 lines, I can't really see any purpose of the final keyword. Is there something I'm missing? Anyone see a reason to do this?
Example 2:
public String getFilepath(){
final File file = new File(this.folder, this.filename);
return file;
}
Since here the actual object is being returned... Does that mean the file variable will be constant/final on the other side...? It doesn't seem to make sense.
In general, it seems to me that you pass a variable, without it's access type. As in, I can have a private variable in a function with a public get function that returns it - but the variable that receives it by calling the function has to specify an access modifier. So if it specifies public, the returned variable will be public in that scope. If it specifies private, the returned variable will be private in that scope. Is there a difference with final? Is the "constancy" of a variable something that can be passed? This strikes me as rather improbable, considering what I know of Java.
Or am I missing the point entirely and there's some other purpose of the final keyword in the above code?
Edit:
I checked back with the original developer who wrote the code, and he said he only put the final keyword in because he had originally thought the method would be a lot longer and wanted to ensure that the file stayed constant throughout. He also said that he generally declares variables that should not be changed as final, as a rule across the board and sort of on principle - a point that both the answers below mentioned. So it seems I was reading too much into a simple extra keyword included for standards reasons. Thanks everyone!
final in this case just means that the local reference file will be immutable. It has no meaning outside the method. Some coding conventions advocate having all variables final unless they need to be mutable so you'll see code like that when someone is following such guidelines.
Some people might tell you that there's a performance benefit to using final, but that is, in no way, conclusively proven.
The primary benefit of the final keyword is for the programmer to indicate that a class, method, or field should not be changed.
Bear in mind that declaring a variable final does not make the referenced object immutable. It just means that the variable cannot have its value reassigned. You can still run methods of the variable file that could change the File object internally.
In the two methods you give, I see no value in making the file variable final. Some code conventions advocate making all variable final unless the need to be modified. Some people don't subscribe to that. I consider it a variation on the precautionary principle.