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.
Related
I know for a fact that static variable is used for all instances of the object whereas the instance variable is used specifically for each instance.
However, what if we declare the instance variable in the beginning and dont touch it in the constructor ? It will act exactly as a static variable right ?
So why bother using both of those ? I'm so confused.
"if we declare the instance variable"
... then it still is an instance variable even if you don't change it in the constructor. As the name says instance variables are for an instance only, i.e. each instance has its own copy which may have the same value. A static or global variable is only one copy that all instances have access to.
Let me make a real world example:
Several people (instances) are in a room and want to get the news.
Instance variables: everyone gets a newspaper and may chose to read it at their own pace or not at all.
Static variable: a TV in the room. Everyone gets the same channel so if anyone switches the channel all others will be affected too.
... and dont touch it in the constructor
Whether you update a variable in the constructor or not doesn't make a variable an instance variable or a global one. It's how they are declared.
Note that you could have instance variables that are changed by other methods only which is perfectly fine in many designs.
Also note that you could change a global variable in a constructor too albeit that wouldn't make much sense in many cases - but there are valid cases.
Static variables can be used without instantiating an object. You can access these without calling class constructor. Instance variables are accessed globally within the class and if you want to use them they have to be public and you must create new object by calling constructor
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 am looking at other peoples' code.
I see a class with no non-static fields but in which most of the methods are non-static, requiring you to make an object to access methods that effectively operate statically.
Is there a possible reason for this, that I am just not understanding?
EDIT
Someone asked for examples. Here is some more info.
For instance there is a file manager class. The only fields are static and are Comparators. There are some methods to do things like sort files in a list, count files, copy files, move files to an archive folder, delete files older than a certain time, or create files (basically take a base name as string, and return a File with given base name and date/time tacked on the end.)
9 non-static methods
5 static methods
I don't see a particular rhyme reason for the ones that are static vs non.
One particularly odd thing is that there are two methods for removing files. One that removes a file no matter what, and one that only removes it if it is empty. The former is a static method while the latter is not. They contain the same exact code except the later first checks if the file.length is 0.
Another odd one is a class that does encryption - all fields and methods are static but it has a constructor that does nothing. And an init() method that checks if a static variable contains an object of itself and if not instantiates an object of itself into that field that is then never actually used. (It seems this is done with a lot of classes - init methods that check for an object of itself in a static variable and if not instantiate itself)
private static File keyfile;
private static String KEYFILE = "enc.key";
private static Scrambler sc;
It has methods to encrypt and decrypt and some methods for dealing with key and file.
Does this make sense to anyone? Am I just not understanding the purpose for this stuff? Or does it seem weird?
Objects don't have to have state. It's a legitimate use case to create an instance of a class with only behaviour.
Why bother to create an instance ? So you can create one and pass it around e.g. imagine some form of calculator which adheres to a particular interface but each instance performs a calculation differently. Different implements of the interface would perform calculations differently.
I quite often create classes with non-static methods and no members. It allows me to encapsulate behaviour, and I can often add members later as the implementation may demand in the future (including non-functionality related stuff such as instrumentation) I don't normally make these methods static since that restricts my future flexibility.
You can certainly do it that way. You should look carefully at what the instance methods are doing. It's perfectly okay if they're all operating only on parameters passed in and static final static class constants.
If that's the case, it's possible to make all those methods static. That's just a choice. I don't know how the original developers would justify either one. Maybe you should ask them.
Let me rephrase this question a bit,
Even though methods are non-static why would one declare fields as static?
I have taken below quoting from Java Docs,
Sometimes, you want to have variables that are common to all objects. This is
accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.
For example, suppose you want to create a number of Bicycle objects and assign each a serial number, beginning with 1 for the first object. This ID number is unique to each object and is therefore an instance variable. At the same time, you need a field to keep track of how many Bicycle objects have been created so that you know what ID to assign to the next one. Such a field is not related to any individual object, but to the class as a whole.
For Bicycle example, kindly refer the Java Docs.
Making all methods non-static allows you to override them. This makes it a lot easier to use this class in testing, because instead of the actual implementation you can use a mock that behaves as you want it for the tests. Static methods are, in my book, a code smell and should be avoided unless there's a good reason (e.g. quite trivial utility methods).
Also, at some point in the future you might want to change the behaviour of the methods in some situation, e.g. in the form of a strategy.
In the case of your encryption class, you might want to hand your class an instance of the encryption class to handle encrypting/decrypting, but be able to configure the details in some other place. That would allow you to change the algorithm and much more easily test your own code without also having to test the encryption.
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.
This question already has answers here:
point of having an instance variable as final?
(6 answers)
Closed 5 years ago.
Suppose we have
final double pi = 3.14159
Should we make above statement static or not?
When we'd want static final vs an instance final?
You should make it static final yes. Possibly public or private... but that's another discussion
In general static finals should be constants or threadsafe objects (such as immutables) that you will construct only once and use across multiple instances of classes.
Instance finals are if you are using it only in that instance, but (wisely) prefer to reduce your state mutability as much as possible.
The two are not necessarily contradictory. For example, you might have a PasswordComplexityPolicy class. This takes a constructor of a bunch of options, all of which are private final instance. But at the top of the class we also have a final public static PasswordComplexityPolicy DEFAULT_POLICY=new PasswordComplexityPolicy(all the stuff needed to construct). Because it's threadsafe, other consumers may choose to use this preconstructed policy rather than build their own. Good for them!
Static variables are bound to the class, so they're created once and use only one spot in memory. For universal constants such as PI, that's perfect.
Instance variables are part of the object instance, so they are stored once per object.
DO NOTE, however, that final variables don't need their value specified in the code. They can perfectly be calculated in the constructor. As such, they are useful when the constant is specific for the object's instance. (Say, you have a Character object that reads its movement speed from a file during creation, but that speed never changes afterwards)
Static final is used for constants like the example you show.
Instance final is used for inmutable classes.
The static final is initialized (stays in memory) when the class is loaded while the instance final is initialized everytime an instance is created. So for this case static final would be a better fit.
Since pi never changes you should use static final here. You'd use an instance final when it's defined as part of the constructor and not known at compile time. If it's always the same value and known at compile time it should be a static final.
Use static when you need only one copy of the constant. If you need a copy for each instance of the class, leave off the static.