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.
Related
I understand that System.setProperty(“key”,”value”) and System.getProperty(“key”) are used to hold and retrieve system properties and user-defined properties. The values set can be accessed everywhere within the application.
Also, I am aware that when a variable is declared public and static, it becomes a constant and is available everywhere within the application.
I would like to know of the 2 which is advantageous and a better option. One aspect I could think of is System.setProperty is useful when we want to retrieve a value in an xml file[using ${key}]. The same can not be achieved using public static variable.
My questions are
Are there any other benefits?
Which one is a better option?
On what scenarios should one go with System.setProperty/getProperty and public static variable?
Thanks in advance.
A Setter can have further tests. Like testing against null, test against bad values etc...
A Setter is usually a better option, yet, a class without Setters could be even better, don't give the user ways of destroying your program
public static Variable variable;
//In other file
variable = null;
And public static variables are not thread-safe at all!!!(Maybe if it's atomic)
Unless dealing with something I really want to be changed a lot, like a Vector2D/3D I never use public static (and in this cases it's not public static anyway because it isn't static). To add to this, I only make it because the user can't null out x,y,z because it's a float/int. Usually I go with methods that do what I want and not simple Setters.
(Ex: Not a good example but I think it shows what I meant. Instead of Person.setState(State.EATING) using Person.eat())
When you run a java program, you are actually starting a JVM instance. That instance will have it's own System properties. That is where you can put your properties. When you run another program, it will have it's own System properties.
A Properties object is a sub-type of Hash-table and it is also thread-safe. But if you want to use a public static variable you also have to handle synchronous access in multi-threaded programs.
For many of my java projects, I use database extensively, what I usually do is to have a property.xml file to hold all my strings and settings.
And then I would have a class CNST to hold all the static constants corresponding to those in the xml file.
Those constants are initialized by the xml file once when the program starts, and used as globals anywhere later on in the program.
However, after reading many articles these days, it seems that using globals at all is not such a good practice. So please can anyone may indicate a good practice fo this situation? Thanks.
In general global variables should be avoided when it is possible => this however is not an issue if they are constants. For cases like this one when you (presumably) initialize this global-settings wrapper object at the beginning and nothing is changed afterwards, there are these options:
Having constants (public static final) which are initialized in static block
Having the variables private static final initialized in static block and exposed via getters
Creating a singleton and having the variables private final exposed via getters
The 2nd and 3rd point has advantage over the 1st that in getter methods you have encapsulated the values of variables and can change/insert code which manipulates the value to be returned to calling method without effecting the (calling) code dependent on it.
Using global variables means they are visible to many classes who can manipulate the data then.
So you will have to take care of your data is it is widely visible.
And if you are using multithreading then you are in trouble as anybody can modify that data, so lots of scope for data getting corrupted.
As a matter of practice i follow following points:
Keep variable visiblity minimal, private if possible.
Make it immutable wherever possible.
You can freely use public static constants or variables. If you use non-static variables then good practice is to use Getters and Setters. If your class conatains only static constants then you can also use private constructor to restrict creating instances of this class.
public class Global {
public static final int A;
public static final int B;
private Global() {} // use only when you have only static fields and methods
static {
A = 1;
B = 2;
}
}
You can create a public static variable instead of Global variable that would be a better idea.
Check out this link.
One other approach is to create a class that follows the singleton pattern, so there can only be one instance of the class and keep the variable in the singleton class and access it with get and set methods.
Edit1:-
Go for the old style in case of declaring the constants. Something like this:-
(public/private) static final TYPE NAME = VALUE;
I would not recommend creating a class in that case.
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.
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.
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.