1. What does static mean in java?
In this tutorial, we will learn everything about the static keyword and its usage in the Java language.
The modifier static keyword is often used to make variables and methods static, which means they are not instance members, they are class members instead. In other words, they are owned by the class itself and not by objects of that class.
Static is also known as a non-access modifier. We add the static keyword so as not to have to instantiate a class to use its class methods and or variables.
A notable example of a static method is the famous public static void main (String[] args)
that every single Java application must have.
The static keyword conventionally goes after the class modifiers (public, default, protected, or private) and before the return type.
public static void main(String[] args) { // write your code here }
1.1 Applicability
The static keyword can be added to the following:
- Initialization blocks.
- Nested classes.
- Methods.
- Variables, except local variables.
1.2 Java Static Scope
Whenever we declare a class member static, it gets loaded and initialized at class loading time and there is only one copy of it in memory as it will be shared with all objects of that class. In other words, the scope (lifetime) of all static members is the same as the class and the application itself.
2. Java Static Initialization Blocks
Initializer Blocks, also known as Static Blocks, get executed at class loading time in memory and only once. They will run before anything else and even before the main
method and you can have as many as you want. To test it out, let’s create an application and add some classes, methods, constructors, and static blocks.
To do so, we just need to add the static keyword anywhere in the class and double curly braces {}
. Everything inside them will run first. Remember, static blocks will get executed in the order you define them in the class should you have multiple blocks.
2.1 Execution Order
Let’s create a new Java application and add a static block to its Main class and print everything out to console so you can see what order each part of our code is being executed.
public class Main { public Main() { System.out.println("Main Class Constructor"); } public static void main(String[] args) { System.out.println("Static Void Main Method"); Main main = new Main(); } static { System.out.println("Main Class Static Block"); } }
As we can see, regardless of where we define the static block is defined, it gets executed before the main method.
Main Class Static Block Static Void Main Method Main Class Constructor
Keep in mind that static blocks get executed only once and to prove that we will add a new class called Outside and add a static block and a constructor. Finally, we will create two instances of that class to prove static blocks run just one time.
public class Outside { static { System.out.println("Static Block in Outside Class!"); } public Outside() { System.out.println("Outside Class Constructor!"); } }
And here is the code inside the main method:
public static void main(String[] args) { Outside outside1 = new Outside(); Outside outside2 = new Outside(); }
Now the output of the above code:
Main Class Static Block Static Block in Outside Class! Outside Class Constructor! Outside Class Constructor!
2.2 Java Static Block Triggers
Bear in mind static blocks will run as soon as any reference to the class is made. To demonstrate that, let’s add a public static boolean
variable to the Outside class and change its Constructor.
public class Outside { static boolean alreadyInstantiated = false; public Outside() { alreadyInstantiated = true; System.out.println("Outside Class Constructor!"); } static { System.out.println("Static Block in Outside Class!"); } }
Now, once any object gets created from this class, the value of the variable will become true, and it will last for as long as the application is running. Our main method will look like this:
public static void main(String[] args) { System.out.println("Has the class been instantiated: " + Outside.alreadyInstantiated); }
Output:
Main Class Static Block Static Block in Outside Class! Has the class been instantiated: false
So here we have learned that static blocks run when the first reference to the class is made. Be it by instantiating an object or accessing one of its static members. In our code, even though no instance of the Outside class was created, because we accessed its static variable, the static code ran first.
2.3 Limitations
- They DO NOT return values.
- They CANNOT be called explicitly.
- They CANNOT access non-static members.
2.4 Usage
One good example where you would use a static block would be when loading drivers, maybe you need to make sure some value will have been registered even before it loads.
2.5 Controversy
If you Google “can static blocks throw exceptions”, a lot of results from Google will say no, it is not possible. However, it is possible to throw Runtime Exceptions or checked Exceptions if inside a try-catch block. To demonstrate that, let’s throw an exception in our code.
Inside the static block in Outside class, we are going to add an if statement and throw new RuntimeException()
.
static { if (true) throw new RuntimeException(); System.out.println("Static Block in Outside Class!"); }
The output:
Main Class Static Block Static Void Main Method Exception in thread "main" java.lang.ExceptionInInitializerError at application.Main.main(Main.java:15) Caused by: java.lang.RuntimeException at application.Outside.<clinit>(Outside.java:14) ... 1 more Process finished with exit code 1
3. Java Static Nested Class
Classes in Java can never be declared as static, if you do, you will get a compiler error saying “Modifier ‘static’ not allowed here”. However, the static keyword is allowed in nested classes (a nested class is a class within another class). It may sound crazy, but it is possible to instantiate a nested static class in Java.
Let’s declare it inside the Outside class then add a constructor and some members.
static class Nested { static final String author = "CodeLearnHub"; public Nested() { System.out.println("Nested Class Constructor!"); } public void objectInstanceMethod() { System.out.println("Nested Class Instance Method!"); } public static void classStaticMethod() { System.out.println("Nested Class Static Method!"); } }
In the main method let’s instantiate a Nested class in order to call its objectInstanceMethod()
. We will also call the static members directly from class. Keep in mind that, although it is NOT recommended, you can access all static members from an object, but you CANNOT access instance members from statics.
public static void main(String[] args) { System.out.println(Outside.Nested.author); Outside.Nested.classStaticMethod(); Outside.Nested nested = new Outside.Nested(); nested.objectInstanceMethod(); }
And here is the output: First we just print out the value of the static variable author, then we call the
CodeLearnHub Nested Class Static Method! Nested Class Constructor! Nested Class Instance Method!
3.1 Accessing Static Members through Objects
This is perfectly possible, but strongly unrecommended. The code below will compile and run normally.
public static void main(String[] args) { Outside.Nested nest = new Outside.Nested(); nest.classStaticMethod(); System.out.println("Author: " + nest.author); }
Check the output:
Nested Class Static Method! Author: CodeLearnHub
3.2 Java Static Accessibility
Bear in mind that every single static member in the Outside class will be accessible to the Nested static class directly regardless of their access modifier (public, default, protected, or private).
3.3 Limitations
- Abstract classes cannot be static.
- Interfaces cannot be static.
- Constructors can never be declared static, which makes sense since constructors are used to creating objects.
4. Java Static Methods
Static methods are owned by the class, NOT the objects. They should be accessed directly via ClassName.methodName()
provided that the method is accessible in the scope.
4.1 Reasons to Use Static Methods
- When they do not depend on objects. They are class members.
- Utility and Helper methods.
- Global members can be easily accessed throughout the application.
4.2 Limitations
- Static methods cannot access instance members, only static ones.
- Static methods cannot be overridden.
- Static methods cannot be abstract.
- Static methods cannot use the keywords
this
andsuper
.
4.3 Code Sample
Let’s write a method to return the number of times a class has been instantiated. Remember, such a method cannot be object dependent. It should keep track of a number of all objects created during the application lifetime.
In the Outside class, let’s add a private static int instanceCount
variable and initialize it to zero.
private static int instanceCount = 0;
Inside the only constructor, we have, increment the counter.
instanceCount++;
Finally, let’s create a getter method to return how many times this class has been instantiated.
public static int getInstanceCount() { return instanceCount; }
Now it is time to create some objects in the main method and test our code.
public static void main(String[] args) { Outside out1 = new Outside(); out1 = new Outside(); Outside out2 = new Outside(); Outside out3 = new Outside(); Outside out4 = new Outside(); System.out.println("Outside class has been instantiated " + Outside.getInstanceCount() + " times."); }
Now let’s check the output of this code. Notice that although we have four variables, we have created 5 different objects or instances if you will.
Outside class has been instantiated 5 times.
5. Java Static Variables (or Fields)
In the same way, static variables are owned by the class and can also be accessed directly without the need for an object. Imagine that you have a variable that holds the value that will be shared across every object. If we don’t make it static, for each instance (object) there will be a copy of that variable in memory holding the very same value, which is not a good idea.
5.1 Reasons to Use Static Variables
- When the value the variable holds doesn’t depend on objects.
- Values that will be shared across all objects. A fitting example would be
Math.PI
.
5.2 Limitations
Different from C++, static variables cannot be declared locally, if you do so, you will get an error: “Static local variables are not allowed“.
6. Conclusion
You should now have a great understanding of static in Java and how, where, and when you should use it. If you would like to delve more into Java programming check more articles on our site.