When Not to Use the Static Keyword in Java

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



Leave a reply



Submit