Java and the use of the Final keyword - java

I'm new to Java having programmed in Delphi and C# for some time,. My question relates to the usage of the "final" keyword on a variable that holds an instantiated class when the variable declaration and instantiation both happen within the scope of the same method. e.g.
private String getDeviceID() {
//get the android device id
final TelephonyManager tm =
(TelephonyManager)GetBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String deviceID = tm.getDeviceId();
// log debug message containing device ID
Log.d(LOG_CAT, "getDeviceID: " + deviceID);
return deviceID;
}
okay so I think I get the fact that "final" variables can only ever be assigned to once and cannot be changed due to the "final" keyword on each declaration, but don't both variables go out of scope when the method exits? and calling the method again will simply reallocate 2 new final variables that once again will go out of scope on method exit?
To me it seems kinda odd to be using the "final" keyword on these variables? unless I don't understand how they impact on local variables within a method's scope?
Can someone enlighten me as to what the impact of "final" is with regard to method scope, or is declaring these particular variables as final just a dumb ass thing that someone did?

final has no effect on scope.
It just prevents the variable from being re-assigned.
It serves as a signal to other developers that these variables will never change, and it prevents you from changing them by accident.
This is particularly useful in longer methods.
final is also required in order to use a variable in an anonymous inner class, since Java does not support true closures.

These variables will indeed be garbage collected as soon as the GC will run when the method exits.
The final keyword is really there as a hint: this variable is instantiated once, you should not touch it in the body of the method itself. Similarly, declaring method parameters final forbids their reuse (which, imho, is a good thing).
Note however that the keyword only affects the object reference: it does not mean that methods on this object reference which modify its internal state will cease to work (typical example: setters).
Another note: when you omit the final keyword, and you don't modify the variable in the body of your method, the JVM is smart enough to optimize this case. So, you may omit it. Whether or not you use it, and where you use it, is a matter of taste/coding style.
And finally, it is good practice to declare public static variables as final: otherwise, anything can modify it! Think string constants etc.

There's nothing special about the scope of a final local variable or parameter.
Declaring a local variable or parameter as final doesn't really do much and is rarely necessary. There are basically two reasons for it:
Some developers believe that anything that doesn't need to be mutable should be immutable. While I agree in principle (immutability is a good thing in many respects), I think that for a language like Java, declaring everything final is going overboard.
If your method contains a local or anonymous inner class and you want any of its local variables or parameters to be accessible to code in the inner class, you have to declare them final. This is a kluge in the Java language; its purpose is to prevent code in the inner class from trying to modify the variables or parameters after they are no longer alive.

They're final to the scope they're in. That's just the way it works.
I imagine the point of making them final in this instance is to prevent future developers from changing them when they shouldn't be changed. It's just defensive coding in this case.

Readability
When it comes to local scope, I find that its usage is variable. That is, some programmers will elect to use it (and abuse it...like me) and some will use it sparingly (e.g. to ensure a class cannot be subclassed, immutability, and etc.).
I find that when working with a group of developers, it's either all, or nothing. Once you start including final modifiers in the local scope, you know that you're hooked and there's not much your team can do (except get you fired...somehow...for being an effective developer).

My perspective
It is a good practice (for better maintenance etc) to make the local variables as final. This is one way of reducing the side effects. Side-effect free code is easy to reason about and hence more readable and easy to maintain.

Overly religious programmers would tell you to mark final on local variables (including method parameters) whenver you can.
In practice nobody does that, including those programmers.
Don't bother.

final is like const in c for primitives and references.

Related

Is it required to set final instance variables in immutable class if copy of mutable objects is returned by getters

Is it required to declare the instance variables as final while creating immutable class provided there are no public setters and private access?
It is not required, as in the compiler won't compile if you don't. But if the variable is immutable, adding final will make your intent clear to other programmers (and yourself when you look at the code again tomorrow and wonder about it), may help the compiler generate more efficient code and will make the compiler complain if later on you do try to change the variable, which may be helpful of course and may indicate that the code change is maybe not ideal, and that you should think of an alternate solution.
No, it is not required: since the private variables are not accessible from subclasses, your class would remain immutable as long as your own code does not violate the immutability rule.
This said, it is certainly a good thing to mark these variables final to protect your code from mistakes of someone else* maintaining your code.
* or even your own mistakes two years from now, when you forget a lot of the details about your class.

Why is it better to use class name instead of objects to access class methods or variables in Java?

I was reading Code Conventions for Java from http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-137265.html#587.
In that, they have mentioned that we should avoid the use of objects to access a class variable or a method and should we use the class name instead.
Avoid using an object to access a class (static) variable or method.
Use a class name instead. For example:
classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //AVOID!
Is there a particular reason for this in terms or performance or something else?
By class variables I assume you mean static variables.
The use of static variables/methods through instance variables should be avoided because it's confusing to the reader. Since you can only use instances to access instance variables, reading a code that calls static methods through an instance can confuse the reader about what's going on.
Image this case, with Thread.sleep, which is a static method:
Thread.sleep(1000);
Since the method is static and we are calling it through the class name, it's intuitive to the reader to deduce that the effect is to put the current thread to sleep.
Now if we did this:
Thread t = new Thread(...);
t.sleep(1000);
Now which thread is put to sleep? The current one "obviously". Someone not knowing about how sleep works might think that the child thread is somehow put to sleep.
I guess it depends on what you want to do.I for one always use the class name to acces a static variable.Being static it doesn matter the way you do it, but i does save some memory usage.
As for nonstatic variables, always use objects.
It is not any different in terms of the bytecode that's produced, so performance is not the issue.
What is the issue is that using a variable to access static members looks as if the reference held by the variable actually matters to what is being accessed. But it does not! In fact even if anObject where null, you would not get a NPE, but it would just call classMethod.
So the principle is simple: when accessing static members, avoid mentioning information (in this case the variable name) that's actually not relevant to the access being made.
I don't know about performance, but clearly another developper looking your code will know at first sight its a static variable/method if you use it with the classname.
I don't think compiler will give different code using a variable though.
it's because.
1.It tells that the variable or method is a static actually.
2.Also, its checked that the object refers to which class. that incurs extra cost.

final variable assignment: at declaration or in constructor?

First of all this is NOT an exact duplicate of Initialize final variable before constructor in Java. It is probably related, but there aren't any answers that satisfy me.
My problem is about final variables in Swing GUI's. It's about custom Actions in particular.
I have a number of final variables and a number of static final variables.
The question is: if the variable is actually a constant, what is better: initialise them at construction-time, or initialise them at declaration?
The answers on the question I mentionned above generally point towards making the variable static as soon as you are able to assign it when you declare it. That doesn't really make sense to me, as the variables aren't used in a static context. I have a couple of Images that my form uses like icons, I made those static because an Image simply is a static thing unless your application modifies them. That makes sense.
On the other hand, the Actions are new instances of a custom inner class. Very technically they are static too, but it just feels different. They simply mustn't be available in static context imo. So do I put:
private final CustomAction customAction = new CustomAction();
Or do I initialise it in the constructor? Which is better? Or am I thinking the wrong way about static?
If the field is a constant, make it a static final member of the class,
public class Foo{
public static final int BAR = ...;
}
Otherwise, initialize the field in the constructor.
Initialize your constant variables at declaration: it is more readable. Make it static if it does not make any sense to put different values into it for different instances of the class, that is, if it is a class level variable, not an instance level.
I think you're on the right track with not making it static, because it sounds like your CustomAction objects are truly custom to the instance of the GUI that creates them in its constructor. I think whether you initialize it in the constructor or not depends on whether your constructor could initialize a CustomAction differently based on the constructor's input arguments.
Where static versus non-static is concerned... a good rule of thumb is, if a variable is going to remain constant across all instances of a particular object type, then that variable should be static. This saves memory over the runtime of your program and also saves CPU time when each object instance is constructed, since that constant won't have to be initialized every time you create a new instance of your Object. On the other hand, if a variable is going to remain constant for a particular instance of an Object, but may be different from instance to instance, then it shouldn't be static.
Finally (pun intended), final should be used whenever you don't want a primitive value or reference to an Object to ever change. The static or non-static context doesn't really influence whether a variable should be final, it's strictly final because the developer doesn't ever want to change that variable. Its static context depends solely on how the developer wants it to be accessed.
For a fast application startup and program parts the user possibly does not visit (About dialog), static is not good. In general static is not very liked as you did find out. There are some reasons, but nothing very convincing. But sometimes it is a anti-pattern or a sign of it.
Still in your case I would refrain from static images. By the way resources are cached internally.

Static Methods or Not? Global variables?

I want to know what way is more efficient.
No global variables, passing variables through parameters, having all methods static
No global variables, having only main method static and creating class object in main to access methods
Use only global variables, having only main method static and creating class object in main to access methods
I am currently using method 3 but I want to know what is more efficient. This class will not be used by any other class outside of it, it pretty much stands alone.
Example of my code structure:
public class myClass {
private int globalVariable;
public static void main(String args[]) {
myClass c;
c.someMethod(); // Changes global variable from method
System.out.println(someMethod); // Prints solution
}
public void someMethod() {...}
}
No class is an island.
There are no silver-bullets, at least its very true in programming.
Premature optimisation is the root of all evil.
In Java we don't have global variables. We only have class variables, instance variables, and method variables.
[Edit]
I am trying to explain here my last point. In fact, bringing the discussion, that is going-on in comments below, to the actual post.
First look at this, an SO thread of C#. There folks are also suggesting the same thing, which is,
There are no global variables in C#". A variable is always locally-scoped. The fundamental unit of code is the class, and within a class you have fields, methods, and properties
I would personally recommend erasing the phrase "global variable" from your vocabulary (this is in the comment section of the original question)
So, here we go.
retort: Classes are globally scoped, and thus all class variables are globally scoped. Hence should be called global.
counter-retort: Not all classes are globally scoped. A class can be package-private. Therefore, the static variables in there will not be visible outside the package. Hence, should not be called as global. Furthermore, classes can be nested, thus can be private as well and definitely can have some static variables but those wouldn't be called global.
retort: public classes are globally scoped, and thus all class variables are globally scoped.
counter-retort: Not exactly. I would like to move the previous argument here but on a variable level. No matter if the class itself is public. The variables in there can be protected, package-private and private. Hence, static variables will not be global in that case.
Now, if you like to call public static variable in public static class, as global then call it by any means. But consider this, when you create a new ClassLoader (as a child of the bootstrap ClassLoader) and load a class that you've already loaded. Then that results in a "very new copy of the class" -- complete with its own new set of statics. Very "un-global", indeed. However, we don't use the word global in Java because it tends to confuse the things and then we need to come with whole lot of explanations just to make everything clear. Folks rightly like to explain the feature of global variables in Java by static variables. There is no problem in that. If you have some problem/code in any other language and that is using global variables and you need to convert that code to Java, then you most likely make use of static variable as an alternative.
A couple of examples I like to render here
When I started Java, instructors like to explain the difference of passing object type variable and primitive variables. And they constantly use the term objects are pass-by-reference, whereas primitives are pass-by-value. Students found this explanation quite confusing. So, we came up with the notion that everything in Java is pass-by-value. And we explain that for objects references are pass-by-value. It becomes much more clear and simple.
Similarly, there are languages which support multiple-inheritance. But Java doesn't, again arguably speaking. But folks tend to explain that feature using interfaces. They explain it by class implementing many interfaces, and call it multiple-inheritance. That's perfectly fine. But what the class, actually, receives by inheriting a number of interfaces. Frankly speaking, nothing. Why?
. Because all the variables in interfaces are implicitly public, final and static, which apparently means those belongs to the class and anyone can access those. Now we can say that perhaps there would be some inner class in the interface, then the class implementing the interface will have it. But again that will be static implicitly and will belong to the interface. Therefore, all what the class will get are methods. And don't forget just the definition and the contract which says, "the class implementing this interface must provide the implementation of all methods or declare itself abstract". Hence, that class will only get responsibilities and nothing much. But that solves our problems in a brilliant way.
Bottom line
Therefore, we say
There are no global variables in Java
Java doesn't support multiple-inheritance, but something like that can be achieved by implementing multiple interfaces. And that really works
There is nothing pass-by-reference in Java, but references are pass-by-value
Now I like to site few more places
Java does not support global, universally accessible variables. You can get the same sorts of effects with classes that have static variables [Ref]
However, extern in ObjectiveC is not an alternative to a class-scoped static variable in Java, in fact it is more like a global variable … so use with caution. [Ref]
In place of global variables as in C/C++, Java allows variables in a class to be declared static [Ref]
Furthermore, the overuse of static members can lead to problems similar to those experienced in languages like C and C++ that support global variables and global functions. [Ref]
All these are inferring one and the same idea. Which is Java doesn't support global variables.
Hell, I wrote that much. Sorry folks.
Performance doesn't matter. You want it as easy to read as possible.
I would do 2 as much as you can. When you really need constants and statics, make constants and statics.
For example, a null safe trim makes a good static method. New upping a StringTrimmer is silly. Putting if null then x else z in 1000 others is silly.
I think this was settled back in 1956 and 1958, when people invented Lisp and ALGOL58 and pondered about modularity, referential transparency, and sound code structure as means to tackle impenetrable spaghetti code that rely on global variables (and who tend to exhibit the software equivalent of the Heisenberg uncertainty principle.)
I mean seriously, this is 2011 and we still wonder about whether to use global variables over encapsulated fields or parameter passing for quote-n-quote efficiency. I mean, seriously.
I may sound arrogant (so be it), but I'll say this:
I can understand some spaces where you have to make some sort of global variable trade-offs (.ie. very resource constrained embedded platforms, for example). I can understand if a person that is just starting in CS (say a freshman) asks this.
But if someone beyond freshman level (let alone someone that does coding for a living and not coding in the most resource barren of environments) asks or even remotely thinks about this as an acceptable thing to do should seriously reconsider going back to the basics (or reconsider this profession - we have too much craptacular code already.)
Short and concise answer: No, it makes no sense. There are no noticeable games. It is not worth it. It leads to craptacular code. And all of these have been known for 50 years now.

Why no global variables in java like C++?

Why there are no global variables in java? If I like to use any variable in all classes of a program then how can I do that?
If you really want to do that, make it a public static variable.
However, you'd be advised to try not to - it makes for less elegant, harder to maintain, harder to test code.
Global variables (in the Java context - public static variables) are bad, because:
harder to maintain - you can't put a breakpoint or log each change to a variable, hence unexpected values at runtime will be very hard to track and fix
harder to test - read Miško Havery's post
harder to read - when someone sees the code he'll wonder:
where does this come from?
where else it is read?
where else it is modified?
how can I know what's its current value?
where is it documented?
To make one clarification that seems needed - variables != constants. Variables change, and that's the problem. So having a public static final int DAYS_IN_WEEK = 7 is perfectly fine - no one can change it.
Some valid global "variables" are constants ;-) for example: Math.PI
C++ is multi-paradigm, whereas Java is pure "almost exclusively"
an object orientated. Object orientated means that every piece of data must be inside of an object.
Please see the links for more information.
Why globals are evil, explained here.
If you need a certain resource that is accessed from any part of your program, have a look at the Singleton Design Pattern.
I just wanted to add that if you want to use a constant global variable its safe. To use it use the final keyword. Example:
public static final int variable;
Global variables do not jive well with OOP. Still one can have constants as global variables. In a sense, singleton are global variables. If you want to have constants as global variables it is better to use enums in stead.
EDIT:
Constants which used to invoked as Class.Constant now can used Constant by using static import. This comes as close as possible to global variables in C++.
package foo;
public class Globals {
public static int count = 3;
}
Then, you can access it anywhere as
int uses_global = foo.Globals.count + 1;
Java is intended to make fully-portable, fully-reusable objects.
By definition, something that depends on a "global variable" is not fully portable or fully reusable. It depends on that global variable existing on the new (reusing) system, and it depends on code on the new (reusing) system manipulating that global variable. At that point, you're better off putting that global variable into an object of its own.

Categories