Ok, so I understand why we should declare an argument to be final from this question, but I don't understand why we shouldn't...
Since Java always uses pass by value, this means that we can't return a new value through the given argument, we can only overwrite it, and make the argument useless therefore, because we don't use the passed value...
Is the only benefit of non-final method arguments in Java the fact that you don't have to make a local variable of the arguments' type?
P.S. This question was triggered by PMD's rule of MethodArgumentCouldBeFinal
I can think of only 2 reasons not to make a parameter final:
to save the use of a local variable if you need to overwrite the parameter's value in some edge cases (for instance to put a default if the param is null etc.).
However, I wouldn't consider that a good practice in general.
to save 6 characters per parameter, which improves readability.
Reason 2 is what leads me not to write it most of the time. If you assume that people follow the practice of never assigning a new value to a parameter, you can consider all parameters as implicitly final. Of course, the compiler won't prevent you from assigning a parameter, but I can live with that, given the gain in readability.
It prevents you from making unintentional error in your code. Rule of thumb here is to make each field and each function argument you know you shouldn't change (I mean reference, you still can change value) in your code as final.
So basically its a mean to prevent programmer from shooting their foot. Nothing more.
Whether you've to declare a local variable final or not (method parameter comes under this), is more of the requirement than a convention. You'll not get a certain answer saying you should always use final or you should never use final. Because that is really a personal preference.
I personally mark the parameters or local variables final when I really don't want their values to be changed, and it even shows my intention to other developers not to overwrite the values. But I don't do it for every parameters. Also for some, using final seems to be noise, as that really increases the code base.
Rule of thumb: Don't use it.
Final cannot stop you changing objects, only its reference, and this is because objects in java are, usually, not inmutable.
Take a look to this code:
class Example{
// think about this class as a simple wrapper, a facade or an adapter
SomeClass inner = new SomeClass();
setInnet(Someclass inner){
this.inner = inner;
}
// delegate methods.....
}
Now, in a method:
private void (final Example examp){
....
examp will be always the same object, but inner can vary... And inner is the important object here, the one which makes everything!
This may be an extreme example, and you may think that inner could be final but, if it's a utillery class, maybe it shouldn't. Also it's easy to find a more common example:
public void (final Map map){;
....
//funny things
....
//and then, in a line, someone does:
map.clear()
// no we have the same reference... but the object has change...
....
So, my point against final in arguments is that it's not guaranteed that all the code inside a final class is inmutable and so the final word can end lying you and mascarading a bug...
By putting final in params you can only show wishes, not facts, and for that you should use comments, not code. Moreover: it's a standar (de facto) in java that all arguments are only input arguments (99% of the code). Thus, final word in params is NOISE because it exists and means nothing.
And I don't like noise. So I try to avoid it.
I only use final word to mark the inner variables that will be used in an anonymous inner class (you can avoid marking it if they are effectively final, but it's cleaner and more readable).
UPDATED
final means 'assigned once' which in applied to method arguments means nothing in a program's logic nor in its design.
You can assign the arguments to a new object inside a method and outside there will not be any change.
The only difference putting final in arguments will be that you will not be able to assign that entities to another objects. Assigning arguments is something which may be ugly and something to avoid but its only a style problem and, at that point, the style problem should be the assignation itself and not the ausence of 'final' word.
I think that final is useless in arguments (and so, noise), but if someone is able to find a use of it I'll be happy to learn it. What can I achieve putting 'final' that cannot achieve without putting it?
Related
I know that:
A blank final class variable must be definitely assigned by a static initializer of the class in which it is declared, or a compile-time error occurs.
A blank final instance variable must be definitely assigned at the end of every
constructor of the class in which it is declared, or a compile-time error occurs.
Why final variable cannot be assigned just once at any time instead of just at declare time?
The corollary to this, for non-final variables, is the initial value of a variable. Every field receives an initial value depending on its type - usually a variant of 0 or null.
It's implied here that, if you're declaring a variable to be final, then you have a specific value in mind that you wish that variable to be assigned and not have changed later in its run. Java doesn't know what value that is, and it likely takes away the convenience of automatically declaring those values for you so to not interfere with the developer's intentions.
That and requiring that all final variables be initialized is to support all variables being definitely assigned before their use. You can use a non-final field that you don't initialize to some value - it'll likely be null though - but you can't use a local variable that you haven't initialized yet for the same reason.
First it is not something against null. The following is legal too:
final String ABC;
{
ABC = null;
}
static final String DEF;
static {
DEF = null:
}
final String GHI = null;
It was the following decision:
When a final field or a local variable is not initialized it can very
well be a bug, forgetting to initialize.
(For normal fields it would be too much boiler code, and zeroing of fields is provided.)
For local variables you might find this obvious. As final variables can only be assigned once, and it was decided that this should happen only during construction (otherwise you would need administration of whether the variable was initialized).
Language design decisions are always a trade off between flexibility and error prevention. In this case, there are some simple questions to check:
In case, there is a code path in which a final variable is not assigned:
How likely is it that the developer declares a final variable just to hold the default value, null, 0 or false?
In contrast, how likely is it that the developer has forgotten the initialization or overlooked a possible code path, in other words, rejecting this code prevents a nasty bug?
How much work is it for the developer, to write the explicit assignment, if (s)he really wants the default value?
I think, trying to answer these questions should lead to the rationale behind this design decision.
This is the place for an important clarification. In case of local variables, all variables must be initialized before use. The restriction is only lifted for non-final heap variables, read, fields and array elements.
In case of arrays, it should be obvious why developers are not enforced to write explicit default values when arrays can be instantiated for lengths up to 2³¹ elements. For non-final instance fields, this decision can be discussed. But such a discussion would be outside the scope of Stackoverflow…
I know that constants are those variables whose values cannot be changed, but if no part of the program changes their value, are they still required to be declared final? And it also seems that they must be static. Why is that?
You are actually asking several questions at once which I am trying to answer.
Why use constants at all?
Constants are used to avoid magic numbers/strings in your code. If you have a string that appears in several occasions of your code, once you have to change that string you only need to change the constant definition and not every occurrence of the string in your code. Also if a constant is only used once it is often a good thing because of its better visibility.
The final keyword.
Its purpose (at least in this context) is twofold. One is to make it impossible to a programmer to change the value. You might have forgotten that it is a constant. The other is to tell the compiler that the value cannot change at runtime. This can be used to create optimized bytecode (e.g. the constant could be removed and every occurrence replaced by its value by the compiler).
The static keyword.
In Java everything is a Class. And every Class can have several instances (objects). If you dont mark your constant as static then every object has "its own constant". Since you dont want that it makes sense to mark it as static. Static fields (or methods) do exist only once per class (as opposed to once per object of the class).
It is certainly possible to declare non-static finals:
class Employee {
final String empId;
public Employee(String empId) { this.empId = empId; }
}
In other cases you want the field to be constant across all instances of the class:
class Color {
final static int BLACK = 0xFFFFFF;
}
As to why you want to declare them final at all instead of just not changing them ever,
It increases program readability, it tells the reader of program something about its behavior that would otherwise have to be in documentation
Compiler reminds if you attempt to change it by mistake
Because static belongs to class rather than any instance.
When it is static single copy shared across all the instances. Where as instance member have the individual copy.
consider you need to increase/decrease game score (count), in each stage (Stage class) of your game.
Normally when you're going to use a constant value on your code, you declare a final static variable. That prevents you from spreading "magic values" around the code, which is not a good practice, for mantainability and legibility reasons.
If you don't declare them final, code made by other people (or you, in case you forget your initial intention) may modify the variable.
If you don't declare them static, every instance of the class you create will have a copy of it, also you'll have to create an instance to get the value. That's not what you want, usually.
We declare constants because we will always need some "magic numbers" that are fixed in the code. Using constants means that they are easier to spot, and that when you change them you will change all of them with a edit.
Imagine that your code defines that your window will show 15 records, and that you will consider people as adults when they are 15 years old. Without constants, changing the size of the windows means that you will have to find the 15 ocurrences, do not miss any, and do not change a 15 that means age by mistake.
The static part is because you do not want to instantiate an object to get a data that is not related to a particular instance (that is exactly what static means, btw, not only when used for constants).
It's not strictly necessary, but it's recommended for reasons of memory-efficiency:
If you don't declare your constant as static every instance of the class (possibly thousands of them) that is created will keep it's own value of (or at least a reference to) that constant in memory, whereas a static member is only kept once per class - and since it's constant anyway, that's sufficient.
I have seen much code where people write public static final String mystring = ...
and then just use a value.
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
UPDATE
Ok, thanks all for all your answers, I understand the meaning of those key (public static final). What I dont understand is why people use that even if the constant will be used only in one place and only in the same class. why declaring it? why dont we just use the variable?
final indicates that the value of the variable won't change - in other words, a constant whose value can't be modified after it is declared.
Use public final static String when you want to create a String that:
belongs to the class (static: no instance necessary to use it), that
won't change (final), for instance when you want to define a String constant that will be available to all instances of the class, and to other objects using the class, and that
will be a publicly accessible part of the interface that the class shows the world.
Example:
public final static String MY_CONSTANT = "SomeValue";
// ... in some other code, possibly in another object, use the constant:
if (input.equals(MyClass.MY_CONSTANT)
Similarly:
public static final int ERROR_CODE = 127;
It isn't required to use final, but it keeps a constant from being changed inadvertently during program execution, and serves as an indicator that the variable is a constant.
Even if the constant will only be used - read - in the current class and/or in only one place, it's good practice to declare all constants as final: it's clearer, and during the lifetime of the code the constant may end up being used in more than one place.
Furthermore using final may allow the implementation to perform some optimization, e.g. by inlining an actual value where the constant is used.
Finally note that final will only make truly constant values out of primitive types, String which is immutable, or other immutable types. Applying final to an object (for instance a HashMap) will make the reference immutable, but not the state of the object: for instance data members of the object can be changed, array elements can be changed, and collections can be manipulated and changed.
Static means..You can use it without instantiate of the class or using any object.
final..It is a keyword which is used for make the string constant. You can not change the value of that string. Look at the example below:
public class StringTest {
static final String str = "Hello";
public static void main(String args[]) {
// str = "world"; // gives error
System.out.println(str); // called without the help of an object
System.out.println(StringTest.str);// called with class name
}
}
Thanks
The keyword final means that the value is constant(it cannot be changed). It is analogous to const in C.
And you can treat static as a global variable which has scope. It basically means if you change it for one object it will be changed for all just like a global variable(limited by scope).
Hope it helps.
static means that the object will only be created once, and does not have an instance object containing it. The way you have written is best used when you have something that is common for all objects of the class and will never change. It even could be used without creating an object at all.
Usually it's best to use final when you expect it to be final so that the compiler will enforce that rule and you know for sure. static ensures that you don't waste memory creating many of the same thing if it will be the same value for all objects.
final indicates that the value cannot be changed once set. static allows you to set the value, and that value will be the same for ALL instances of the class which utilize it. Also, you may access the value of a public static string w/o having an instance of a class.
public makes it accessible across the other classes. You can use it without instantiate of the class or using any object.
static makes it uniform value across all the class instances.
It ensures that you don't waste memory creating many of the same thing if it will be the same value for all the objects.
final makes it non-modifiable value. It's a "constant" value which is same across all the class instances and cannot be modified.
You do not have to use final, but the final is making clear to everyone else - including the compiler - that this is a constant, and that's the good practice in it.
Why people doe that even if the constant will be used only in one place and only in the same class: Because in many cases it still makes sense. If you for example know it will be final during program run, but you intend to change the value later and recompile (easier to find), and also might use it more often later-on. It is also informing other programmers about the core values in the program flow at a prominent and combined place.
An aspect the other answers are missing out unfortunately, is that using the combination of public final needs to be done very carefully, especially if other classes or packages will use your class (which can be assumed because it is public).
Here's why:
Because it is declared as final, the compiler will inline this field during compile time into any compilation unit reading this field. So far, so good.
What people tend to forget is, because the field is also declared public, the compiler will also inline this value into any other compile unit. That means other classes using this field.
What are the consequences?
Imagine you have this:
class Foo {
public static final String VERSION = "1.0";
}
class Bar {
public static void main(String[] args) {
System.out.println("I am using version " + Foo.VERSION);
}
}
After compiling and running Bar, you'll get:
I am using version 1.0
Now, you improve Foo and change the version to "1.1".
After recompiling Foo, you run Bar and get this wrong output:
I am using version 1.0
This happens, because VERSION is declared final, so the actual value of it was already in-lined in Bar during the first compile run. As a consequence, to let the example of a public static final ... field propagate properly after actually changing what was declared final (you lied!;), you'd need to recompile every class using it.
I've seen this a couple of times and it is really hard to debug.
If by final you mean a constant that might change in later versions of your program, a better solution would be this:
class Foo {
private static String version = "1.0";
public static final String getVersion() {
return version;
}
}
The performance penalty of this is negligible, since JIT code generator will inline it at run-time.
Usually for defining constants, that you reuse at many places making it single point for change, used within single class or shared across packages. Making a variable final avoid accidental changes.
Why do people use constants in classes instead of a variable?
readability and maintainability,
having some number like 40.023 in your code doesn't say much about what the number represents, so we replace it by a word in capitals like "USER_AGE_YEARS". Later when we look at the code its clear what that number represents.
Why do we not just use a variable? Well we would if we knew the number would change, but if its some number that wont change, like 3.14159.. we make it final.
But what if its not a number like a String? In that case its mostly for maintainability, if you are using a String multiple times in your code, (and it wont be changing at runtime) it is convenient to have it as a final string at the top of the class. That way when you want to change it, there is only one place to change it rather than many.
For example if you have an error message that get printed many times in your code, having final String ERROR_MESSAGE = "Something went bad." is easier to maintain, if you want to change it from "Something went bad." to "It's too late jim he's already dead", you would only need to change that one line, rather than all the places you would use that comment.
public makes it accessible across other classes.
static makes it uniform value across all the class instances.
final makes it non-modifiable value.
So basically it's a "constant" value which is same across all the class instances and which cannot be modified.
With respect to your concern "What I don't understand is why people use that even if the constant will be used only in one place and only in the same class. Why declaring it? Why don't we just use the variable?"
I would say since it is a public field the constant value can also be used elsewhere in some other class using ClassName.value. eg: a class named Math may have PI as final static long value which can be accessed as Math.PI.
It is kind of standard/best practice.
There are already answers listing scenarios, but for your second question:
Why do they have to do that? Why do they have to initialize the value as final prior to using it?
Public constants and fields initialized at declaration should be "static final" rather than merely "final"
These are some of the reasons why it should be like this:
Making a public constant just final as opposed to static final leads to duplicating its value for every instance of the class, uselessly increasing the amount of memory required to execute the application.
Further, when a non-public, final field isn't also static, it implies that different instances can have different values. However, initializing a non-static final field in its declaration forces every instance to have the same value owing to the behavior of the final field.
This is related to the semantics of the code. By naming the value assigning it to a variable that has a meaningful name (even if it is used only at one place) you give it a meaning. When somebody is reading the code that person will know what that value means.
In general is not a good practice to use constant values across the code. Imagine a code full of string, integer, etc. values. After a time nobody will know what those constants are. Also a typo in a value can be a problem when the value is used on more than one place.
I think these are all clear explanations. But, Let me clarify it by giving a java inbuild example.
In java, most would have used System.out.println()
The system is a class and out is a PrintStream class.
So what java says is I will take care of the initialization of the out object(PrintStream) and keep the initialization private to myself in the System class.
public final class System {
public final static PrintStream out = null;
//Some initialization done by system class which cannot be changed as it is final.
}
You just access the println method statically without worrying about its initialization.
I personally quite like instance initializers - I use them to assign default values to things such as collections so when writing constructors I don't have to remember to assign them the same default values each time. It seems quite elegant to me - avoids annoying NPE's popping up and avoids duplicate code. A private method doesn't seem as nice because a) it can't assign values to final fields, b) it could be run elsewhere in code and c) the method still needs to be explicitly called at the start of each constructor.
However, the flip side with others I have spoken to is that they're confusing, some people reading the code might not understand what they do or when they're called and thus they could cause more problems than they solve.
Are proper use of these initializers something to be encouraged or avoided? Or is it an "each to their own" case?
It depends, for instance on the level of knowledge about Java readers of your code can be expected to have, and whether the alternatives are practical.
Alternatives are:
inline into every constructor. If there are several constructors, this violates DRY.
have all constructor delegate to the same constructor, and put the code in that one. If the constructors are non-trivial, and take different arguments, this might require to write a new constructor that receives the values of all fields in its arguments. If there are many fields, this can get rather lengthy (and hard to read, since it is not obvious which value is being assigned to which field)
have all constructors invoke an init method. Can't assign final fields that way. Should probably prevent the method from being overridden. Might want to prevent it from being called several times.
Since initializers are uncommon, you should only prefer them when there is a clear advantage to using them. My most recent use of one was:
private final Collator collator = Collator.getInstance();
{
collator.setStrength(Collator.SECONDARY);
}
in a class with several constructors with rather different argument lists and half a dozen other fields.
I don't really use them but one case I can see them useful is when you have multiple constructors, not calling themselves (this(..)), that need some common initialization logic shared, and no need to create a specific private method for that.
Oh and the only place I use instance initializers are for quickly initialize in one-line Maps for instance, eg:
Map<String,String> m = new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}};
Could be useful to initialize a map in let's say an interface
interface A {
Map<String,String> PROPS = Collections.unmodifiableMap(new HashMap<String,String>(){{
put("a","b");
put("c","b");
put("d","b");
}});
}
Still doing so you end up with a annonymous subclass of HashMap...
It is better to overload your constructor and have as many constructor variations as you like. The best example is Java's Arraylist. It has two constructors. One that takes a integer as an argument and other being a default constructor. If you take a look at the default constructor, it infact calls the Single argument constructor with a constant value 10.
List<Object> x = new ArrayList<Object>(); //Creates with default capacity 10
List<Object> y = new ArrayList<Object>(40); //Creates with the specified capacity 40
I would stay they are preferred. But based on the other responses it appears it might be more "to each his own". I like them because it keeps the related information together. Rather than declaring a value and setting it in the constructor, you can do it all in one place.
You can use a constructor with parameters and this constructor calls the private setters. And than implement a default constructor who calls that contructor with default values. If you want assign default values to properties, do it in the declaration.
The instance and static initializers are good to init complex datastructures like matrices or cubes.
By the way, a final property is mostly called a constant.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In Java, there is a practice of declaring every variable (local or class), parameter final if they really are.
Though this makes the code a lot more verbose, this helps in easy reading/grasping of the code and also prevents mistakes as the intention is clearly marked.
What are your thoughts on this and what do you follow?
I think it all has to do with good coding style. Of course you can write good, robust programs without using a lot of final modifiers anywhere, but when you think about it...
Adding final to all things which should not change simply narrows down the possibilities that you (or the next programmer, working on your code) will misinterpret or misuse the thought process which resulted in your code. At least it should ring some bells when they now want to change your previously immutable thing.
At first, it kind of looks awkward to see a lot of final keywords in your code, but pretty soon you'll stop noticing the word itself and will simply think, that-thing-will-never-change-from-this-point-on (you can take it from me ;-)
I think it's good practice. I am not using it all the time, but when I can and it makes sense to label something final I'll do it.
Obsess over:
Final fields - Marking fields as final forces them to be set by end of construction, making that field reference immutable. This allows safe publication of fields and can avoid the need for synchronization on later reads. (Note that for an object reference, only the field reference is immutable - things that object reference refers to can still change and that affects the immutability.)
Final static fields - Although I use enums now for many of the cases where I used to use static final fields.
Consider but use judiciously:
Final classes - Framework/API design is the only case where I consider it.
Final methods - Basically same as final classes. If you're using template method patterns like crazy and marking stuff final, you're probably relying too much on inheritance and not enough on delegation.
Ignore unless feeling anal:
Method parameters and local variables - I RARELY do this largely because I'm lazy and I find it clutters the code. I will fully admit that marking parameters and local variables that I'm not going to modify is "righter". I wish it was the default. But it isn't and I find the code more difficult to understand with finals all over. If I'm in someone else's code, I'm not going to pull them out but if I'm writing new code I won't put them in. One exception is the case where you have to mark something final so you can access it from within an anonymous inner class.
You really need to understand the full use of the final keyword before using it. It can apply to and has differing affects on variables, fields, methods and classes
I’d recommend checking out the article linked to below for more details.
Final Word On the final Keyword
The final modifier, especially for variables, is a means to have the compiler enforce a convention that is generally sensible: make sure a (local or instance) variable is assigned exactly once (no more no less). By making sure a variable is definitely assigned before it is used, you can avoid common cases of a NullPointerException:
final FileInputStream in;
if(test)
in = new FileInputStream("foo.txt");
else
System.out.println("test failed");
in.read(); // Compiler error because variable 'in' might be unassigned
By preventing a variable from being assigned more than once, you discourage overbroad scoping. Instead of this:
String msg = null;
for(int i = 0; i < 10; i++) {
msg = "We are at position " + i;
System.out.println(msg);
}
msg = null;
You are encouraged to use this:
for(int i = 0; i < 10; i++) {
final String msg = "We are at position " + i;
System.out.println(msg);
}
Some links:
The final story (free chapter of the book "Hardcore Java")
Some final patterns
Definite assignment
I'm pretty dogmatic about declaring every possible variable final. This includes method parameters, local variables, and rarely, value object fields. I've got three main reasons for declaring final variables everywhere:
Declaring Intention: By declaring a final variable, I am stating that this variable is meant to be written to only once. It's a subtle hint to other developers, and a big hint to the compiler.
Enforcing Single-use Variables: I believe in the idea that each variable should have only one purpose in life. By giving each variable only one purpose, you reduce the time it takes to grok the purpose of that particular variable while debugging.
Allows for Optimization: I know that the compiler used to have performance enhancement tricks which relied specifically on the immutability of a variable reference. I like to think some of these old performance tricks (or new ones) will be used by the compiler.
However, I do think that final classes and methods are not nearly as useful as final variable references. The final keyword, when used with these declarations simply provide roadblocks to automated testing and the use of your code in ways that you could have never anticipated.
Effective Java has an item that says "Favour immutable objects". Declaring fields as final helps you take some small steps towards this, but there is of course much more to truly immutable objects than that.
If you know that objects are immutable they can be shared for reading among many threads/clients without synchronization worries, and it is easier to reason about how the program runs.
I have never been in a situation where having a final keyword on a variable has stopped me from making a mistake, so for the moment I think it's a giant waste of time.
Unless there is a real reason for doing it (as in you want to make a specific point about that variable being final) I would rather not do it since I find it makes the code less readable.
If, however, you don't find it makes the code harder to read or longer to write then by all means go for it.
Edit: As a clarification (and an attempt to win back down-votes), I'm not saying don't mark constants as final, I'm saying don't do stuff like:
public String doSomething() {
final String first = someReallyComplicatedExpressionToGetTheString();
final String second = anotherReallyComplicatedExpressionToGetAnother();
return first+second;
}
It just makes code (in my opinion) harder to read.
It's also worth remembering that all final does is prevent you from reassigning a variable, it doesn't make it immutable or anything like that.
Final should always be used for constants. It's even useful for short-lived variables (within a single method) when the rules for defining the variable are complicated.
For example:
final int foo;
if (a)
foo = 1;
else if (b)
foo = 2;
else if (c)
foo = 3;
if (d) // Compile error: forgot the 'else'
foo = 4;
else
foo = -1;
Sounds like one of the biggest argument against using the final keyword is that "it's unnecessary", and it "wastes space".
If we acknowledge the many benefits of "final" as pointed out by many great posts here, while admitting it takes more typing and space, I would argue that Java should have made variables "final" by default, and require that things be marked "mutable" if the coder wants it to be.
I use final all the time for object attributes.
The final keyword has visibility semantics when used on object attributes. Basically, setting the value of a final object attribute happens-before the constructor returns. This means that as long as you don't let the this reference escape the constructor and you use final for all you attributes, your object is (under Java 5 semantics) guarenteed to be properly constructed, and since it is also immutable it can be safely published to other threads.
Immutable objects is not just about thread-safety. They also make it a lot easier to reason about the state transitions in your program, because the space of what can change is deliberately and, if used consistently, thoroughly limited to only the things that should change.
I sometimes also make methods final, but not as often. I seldomly make classes final. I generally do this because I have little need to. I generally don't use inheritance much. I prefer to use interfaces and object composition instead - this also lends itself to a design that I find is often easier to test. When you code to interfaces instead of concrete classes, then you don't need to use inheritance when you test, as it is, with frameworks such as jMock, much easier to create mock-objects with interfaces than it is with concrete classes.
I guess I should make the majority of my classes final, but I just haven't gotten into the habbit yet.
I have to read a lot of code for my job. Missing final on instance variables is one of the top things to annoy me and makes understanding the code unnecessarily difficult. For my money, final on local variables causes more clutter than clarity. The language should have been designed to make that the default, but we have to live with the mistake. Sometimes it is useful particularly with loops and definite assignment with an if-else tree, but mostly it tends to indicate your method is too complicated.
final should obviously be used on constants, and to enforce immutability, but there is another important use on methods.
Effective Java has a whole item on this (Item 15) pointing out the pitfalls of unintended inheritance. Effectively if you didn't design and document your class for inheritance, inheriting from it can give unexpected problems (the item gives a good example). The recommendation therefore is that you use final on any class and/or method that wasn't intended to be inherited from.
That may seem draconian, but it makes sense. If you are writing a class library for use by others then you don't want them inheriting from things that weren't designed for it - you will be locking yourself into a particular implementation of the class for back compatibility. If you are coding in a team there is nothing to stop another member of the team from removing the final if they really have to. But the keyword makes them think about what they are doing, and warns them that the class they are inheriting from wasn't designed for it, so they should be extra careful.
Another caveat is that many people confuse final to mean that the contents of the instance variable cannot change, rather than that the reference cannot change.
Even for local variables, knowing that it is declared final means that I don't need to worry about the reference being changed later on. This means that when debugging and I see that variable later on, I am confident that it is referring to the same object. That is one less thing I need to worry about when looking for a bug.
A bonus is that if 99% of variables are declared final, then the few variables which really are variable stand out better.
Also, the final lets the compiler find some more possible stupid mistakes that might otherwise go unnoticed.
Choosing to type final for each parameter in each method will produce so much irritation both for coders and code readers.
Once irritation goes beyond reasonable switch to Scala where arguments are final by default.
Or, you can always use code styling tools that will do that automatically for you. All IDEs have them implemented or as plugins.
Final when used with variables in Java provides a substitute for constant in C++. So when final and static is used for a variable it becomes immutable. At the same time makes migrated C++ programmers pretty happy ;-)
When used with reference variables it does not allow you to re-reference the object, though the object can be manipulated.
When final is used with a method, it does not allow the method to be over-ridden by the subclasses.
Once the usage is very clear it should be used with care. It mainly depends on the design as using final on the method would not help polymorphism.
One should only use it for variables when you are damn sure that the value of the variable will/should never be changed. Also ensure that you follow the coding convention encouraged by SUN.for eg: final int COLOR_RED = 1; (Upper case seperated by underscore)
With a reference variable, use it only when we need a an immutable reference to a particular object.
Regarding the readability part, ensue that comments play a very important role when using the final modifier.
I never use them on local variables, there is little point for the added verbosity. Even if you don't think the variable should be reassigned, that will make little difference to the next person altering that code that thinks otherwise, and since the code is being changed, any original purpose for making it final may no longer be valid. If it is just for clarity, I believe it fails due to the negative effects of the verbosity.
Pretty much the same applies to member variables as well, as they provide little benefit, except for the case of constants.
It also has no bearing on immutability, as the best indicator of something being immutable is that it is documented as such and/or has no methods that can alter the object (this, along with making the class final is the only way to guarantee that it is immutable).
But hey, that's just my opinion :-)
I set up Eclipse to add final on all fields and attributes which are not modified. This works great using the Eclipse "save actions" which adds these final modifiers (among other things) when saving the file.
Highly recommended.
Check out my blog post of Eclipse Save Actions.
For arguments I'm think they're not needed. Mostley they just hurt readabillity. Rreassigning an argument variable is so insanely stupid that I should be pretty confident that they can be treated as constants anyway.
The fact that Eclipse colors final red makes it easier to spot variable declarations in the code which I think improves readbillity most of the time.
I try to enforce the rule that any and all variables should be final it there isn't an extremley valid reason not to. It's so much easier to answer the "what is this variable?" question if you just have to find the initilization and be confident that that is it.
I actually get rather nervous around non-final variables now a days. It's like the differnce between having a knife hanging in a thread abouve your head, or just having it you kitchen drawer...
A final variable is just a nice way to lable values.
A non-final variable is bound to part of some bug-prone algorithm.
One nice feature is that when the option to use a variable in out of the question for an algorithm most of the time the sollution is to write a method instead, which usually improves the code significantly.
I've been coding for a while now and using final whenever I can. After doing this for a while (for variables, method parameters and class attributes), I can say that 90% (or more) of my variables are actually final. I think the benefit of NOT having variables modified when you don't want to (I saw that before and it's a pain sometimes) pays for the extra typing and the extra "final" keywords in your code.
That being said, if I would design a language, I would make every variable final unless modified by some other keyword.
I don't use final a lot for classes and methods, thought. This is a more or less complicated design choice, unless your class is a utility class (in which case you should have only one private constructor).
I also use Collections.unmodifiable... to create unmodifiable lists when I need to.
Using anonymous local classes for event listeners and such is a common pattern in Java.
The most common use of the final keyword is to make sure that variables in scope are accessible to the even listener.
However, if you find yourself being required to put a lot of final statements in your code. That might be a good hint you're doing something wrong.
The article posted above gives this example:
public void doSomething(int i, int j) {
final int n = i + j; // must be declared final
Comparator comp = new Comparator() {
public int compare(Object left, Object right) {
return n; // return copy of a local variable
}
};
}
I use it for constants inside and outside methods.
I only sometimes use it for methods because I don't know if a subclass would NOT want to override a given method(for whatever reasons).
As far as classes, only for some infrastructure classes, have I used final class.
IntelliJ IDEA warns you if a function parameter is written to inside a function. So, I've stopped using final for function arguments. I don't see them inside java Runtime library as well.
I hardly use final on methods or classes because I like allowing people to override them.
Otherwise, I only use finally if it is a public/private static final type SOME_CONSTANT;
Marking the class final can also make some method bindings happen at compile time instead of runtime.
Consider "v2.foo()" below - the compiler knows that B cannot have a subclass, so foo() cannot be overridden so the implementation to call is known at compile time. If class B is NOT marked final, then it's possible that the actual type of v2 is some class that extends B and overrides foo().
class A {
void foo() {
//do something
}
}
final class B extends A {
void foo() {
}
}
class Test {
public void t(A v1, B v2) {
v1.foo();
v2.foo();
}
}
Using final for constants is strongly encouraged. However, I wouldn't use it for methods or classes (or at least think about it for a while), because it makes testing harder, if not impossible. If you absolutely must make a class or method final, make sure this class implements some interface, so you can have a mock implementing the same interface.