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.
Related
In my java program I use a Constants.java class. In this class I created about 50 Strings properties in this way
public static final String startError = "The program could not be started, please ......";
public static final String logPath="/Users/hgvu/";
In my program I use this class in this way for example
System.out.println(Constants.startError);
I am new in the domain, do you think it's a good idea to make fields in the Constants class static ?
Make your class final, like public final class Constants. And Java doesn't let you create top-level static classes, I think you meant making fields static when you asked "do you think it's a good idea to make the Constants class static". The answer is yes, it is the best way to go about it.
In my opinion Constants should not vary - therefore they should always be static... This also means you can access the constant variable values without having to initiate the Constants.java class
you wont be able to define a Static class in java unless it is nested, but if you want the constants to be shared across, then making it a nested class does not make any buyout.
But you can make your class final and have private constructor would be a good choice if you want this class to only contain your constants
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.
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.
I have an encryption utility method that relies on an external dependency --- a cipher key which is being retrieved from a property file. The way it can be retrieved in the current code base which I inherited is that it relies on creating new objects to be able to get the value of a property in the properties file. For example, if wanted to get the Cipher Key from the property file, it would be like this:
public synchronized static String encrypt(String someTextToEncrypt) {
String propertyValue = null;
propertyValue = getProcessCommonBase().
getProcessProperties.getProperty("CIPHER_KEY");
/*encrypt algorithm*/
return encryptedForm;
}
private synchronized static ProcessCommonBase getProcessCommonBase() {
if (processCommonBase == null) {
processCommonBase = new ProcessCommonBase();
}
return processCommonBase;
}
private static ProcessCommonBase processCommonBase;
EDITED: Design-wise is having a something like the processCommonBase instance variable a good practice to do? My understanding is that a good practice is that static variables should be final and do not change. In this case, however, the ProcessCommonBase class maintains state and is subject to change.
NEW QUESTION: If the static method relies on something external shouldn't I just mark the method and the processCommon base variable as non static and in Spring, just make a bean definition for it? What is better?
I agree with Joonas. I don't see why not make the variable final. Could you elaborate please what exactly do you mean by this:
My understanding is that a good practice is that static variables should be final and do not change. In this case, however, the ProcessCommonBase class maintains state and is subject to change.
Even if the variable is final, you still can change the object it references to in exactly the same ways as you'd do it with a non-final variable. That's why it's perfectly fine for a static method to have a static variable maintaining its state, but nothing stops you from actually making it final in this case. Why not do this:
private static ProcessCommonBase processCommonBase = new ProcessCommonBase();
Maybe there's something stopping you from creating processCommonBase at static initialization time, but it isn't obvious from the information you have provided.
Someone already commented your specific case, but in general, what you described is an effectively final static variable, which is just created "lazily" (that is, only when needed). It's a fine approach, if creating a ProcessCommonBase instance is an expensive and rare event, although you must be careful to access it only via the getter method then. On the other hand, if a ProcessCommonBase will be created whenever the surrounding class is used, then making it actually final is a better approach: it's simpler (less error prone, as you don't need to remember to use the getter method exclusively), and will actually be a bit cheaper, as the final variable is initialized only when the surrounding class is first used, and you don't need the (synchronized!) null check every time when accessing it (of course, if you use > 1 threads andProcessCommonBase isn't thread-safe, then you need to synchronize somewhere).
Answer to your second question: being static vs. not and relying on some external system properties are two separate things. I don't know what Spring does, but if your method essentially a function - "value in, result out" - then it's a static method by its nature, even if it reads its configuration from some system property. Making such methods instance methods is possible, but if it only complicates things and gives nothing, why bother?
The usage of static is often frowned upon from an OO design perspective because it gives tight coupling between objects. With statics methods it’s impossible to decouple an interface from its actual implementation. This lack of decoupling can for example become a problem when you want to unit test a single class, as it can’t be separated from the other static parts.
In today’s Java landscape you’re singleton crypt class can be much better designed with the help of Dependency Injection (DI). The ProcessCommonBase could also be implemented as an DI singleton if it didn’t had that very strong code smell, because if it’s a god-object then it should be refactored, for example by using DI for injecting properties into you crypt class.
Example code based on Google Guice:
#Singleton
public MyCrypt {
private final key;
#Inject
MyCrypt(#CipherKey String key) {
this.pBase = pBase;
}
public synchronized String encrypt(String someTextToEncrypt) {
/*encrypt algorithm*/
return encryptedForm;
}
}
Configuring DI properties:
public class PropertiesModule extends AbstractModule {
#Override
protected void configure() {
String key = .. what ever ..
bind(String.class).annotatedWith(CiperKey.class).toInstance(key);
}
More DI examples can be found here:
http://java.dzone.com/articles/cdi-overview-part-1
Populair Java DI implementations are: Guice, Spring and Java EE6.
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.