When NOT to use the static keyword in Java?
One reason why you may not want it to be static is to allow it to be overridden in a subclass. In other words, the behaviour may not depend on the data within the object, but on the exact type of the object. For example, you might have a general collection type, with an isReadOnly
property which would return false
in always-mutable collections, true
in always-immutable collections, and depend on instance variables in others.
However, this is quite rare in my experience - and should usually be explicitly specified for clarity. Normally I'd make a method which doesn't depend on any object state static.
When to use static methods
One rule-of-thumb: ask yourself "Does it make sense to call this method, even if no object has been constructed yet?" If so, it should definitely be static.
So in a class Car
you might have a method:
double convertMpgToKpl(double mpg)
...which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car
. But this method (which sets the efficiency of one particular Car
):
void setMileage(double mpg)
...can't be static since it's inconceivable to call the method before any Car
has been constructed.
(By the way, the converse isn't always true: you might sometimes have a method which involves two Car
objects, and still want it to be static. E.g.:
Car theMoreEfficientOf(Car c1, Car c2)
Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car
is more important, you shouldn't force a caller to choose one Car
as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.
What does the 'static' keyword do in a class?
static
members belong to the class instead of a specific instance.
It means that only one instance of a static
field exists[1] even if you create a million instances of the class or you don't create any. It will be shared by all instances.
Since static
methods also do not belong to a specific instance, they can't refer to instance members. In the example given, main
does not know which instance of the Hello
class (and therefore which instance of the Clock
class) it should refer to. static
members can only refer to static
members. Instance members can, of course access static
members.
Side note: Of course, static
members can access instance members through an object reference.
Example:
public class Example {
private static boolean staticField;
private boolean instanceField;
public static void main(String[] args) {
// a static method can access static fields
staticField = true;
// a static method can access instance fields through an object reference
Example instance = new Example();
instance.instanceField = true;
}
[1]: Depending on the runtime characteristics, it can be one per ClassLoader or AppDomain or thread, but that is beside the point.
Why are static variables considered evil?
Static variables represent global state. That's hard to reason about and hard to test: if I create a new instance of an object, I can reason about its new state within tests. If I use code which is using static variables, it could be in any state - and anything could be modifying it.
I could go on for quite a while, but the bigger concept to think about is that the tighter the scope of something, the easier it is to reason about. We're good at thinking about small things, but it's hard to reason about the state of a million line system if there's no modularity. This applies to all sorts of things, by the way - not just static variables.
Is there any need to use static keyword for final variables in Java?
static
and final
are different concepts. A static
member belongs to a class instead of an instance whereas you can not re-assign a final
variable.
MyClass.myVariable = 5; //This change is reflected in both instances
➡️ It would not have been possible had myVariable
been declared final
.
Can I change the order of final and static keywords e.g.
public static final int ERROR_CODE = 200; or
public final static int ERROR_CODE = 200;
➡️ Yes. It doesn't make any difference.
Why can't we use 'this' keyword in a static method
Because this
refers to the object instance. There is no object instance in a call of a static method. But of course you can access your static field (only the static ones!). Just use
class Sub {
static int y;
public static void foo() {
y = 10;
}
}
If you want to make sure you get the static field y
and not some local variable with the same name, use the class name to specify:
class Sub {
static int y;
public static void foo(int y) {
Sub.y = y;
}
}
How does the static keyword work in Java?
Where is this copy stored?
The copy (static variable) is stored in the Permanent Generation section, but if you use Java8 the Permanent Generation section no longer exists.
The static variables and static methods are part of the reflection data which are class-related data and not instance-related.
How do the objects access that copy?
Every instance of class (object) that you have created has a reference to the class.
When is this copy created?
It is created at runtime when the class is loaded: this is done by the classloader of the JVM when the class is first referenced.
Static variables belong to the class, and not to instances of the class.
Your intuition is right - you have only one copy regardless of how many object you create.
You can access a static variable using the name of the class, like in this example:
class Static {
static int staticField;
}
public class UseStatic {
public static void main(String[] args) {
System.out.println(Static.staticField);
}
}
The static fields are useful to create some kind of class constants.
Finally, to easily initialize a static field of a specific class you can use Static Initialization Blocks.
Sources: University course on java, java official documentation
In Java, is there any disadvantage to static methods on a class?
The main disadvantage is that you cannot swap, override or choose method implementations at runtime.
Related Topics
Create Java Runtime Image on One Platform for Another Using Jlink
Where Is the Correct Location to Put Log4J.Properties in an Eclipse Project
Tomcat7 Starts Too Late on Ubuntu 14.04 X64 [Digitalocean]
Annotations from Javax.Validation.Constraints Not Working
Exclude Methods from Code Coverage with Cobertura
Problems Connecting via Https/Ssl Through Own Java Client
Java If VS. Try/Catch Overhead
Does Stream.Foreach Respect the Encounter Order of Sequential Streams
Print Full Call Stack on Printstacktrace()
Arrays.Fill with Multidimensional Array in Java
Which Loop Has Better Performance? Why
Sslhandshakeexception: No Subject Alternative Names Present
Java Try/Catch/Finally Best Practices While Acquiring/Closing Resources
How Much Memory Does a String Use in Java 8