Core Java

Java Static Keyword Example

1. Introduction

In this post, we feature a comprehensive example of the Java Static Keyword. We are also going to see the static variable in Java. Java programming language defines a list of keywords. Here is the static keyword definition from Oracle:

static is a keyword which defines a variable as a class variable. Classes maintain one copy of class variables regardless of how many instances exist of that class. A “static” keyword can also be used to define a method as a class method. Class methods are invoked by the class instead of a specific instance, and can only operate on class variables.

The static variables are loaded during the class-loading process and not collected by the garbage collector. Therefore, the developer should consider the size of static variables to avoid running out of memory.

what does static mean in java

In this example, I will demonstrate how to:

  • Define and use a static variable in a class or in an interface in Java
  • Define and use a static method in a class or in an interface in Java
  • Define and use a static block in a class
  • Define and use a nested static class

2. Technologies Used

The example code in this article was built and run using:

  • Java 11
  • Maven 3.3.9
  • Eclipse Oxygen
  • Junit 5.5.2

3. Maven Project

3.1 Dependencies

I will include Junit in the pom.xml.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>jcg-zheng-demo</groupId>
	<artifactId>jcg-static-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<properties>
		<junit-jupiter.version></junit-jupiter.version>
	</properties>

	<build>

		<sourceDirectory>src/main/java</sourceDirectory>
		<testSourceDirectory>src/test/java</testSourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.0</version>
				<configuration>
					<release>11</release>
				</configuration>
			</plugin>
		</plugins>
	</build>
	<dependencies>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<version>5.5.2</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-api</artifactId>
			<version>5.5.2</version>
			<scope>test</scope>
		</dependency>

	</dependencies>
</project>

3.2 DemoClass

In this step, I will create DemoClass which has:

  • a nested static class – DemoStaticClass. Please note that nested static class can only be created inside a class. It can only access the outer-class’s static attributes and methods.
  • a static String attribute – commonMsg
  • a static int attribute – instanceCount
  • two static blocks to initialize two static attributes. Please note the static blocks are executed based on its order.
  • a static method – getInstanceCount()
  • void sayHello() – which creates an object of DemoStaticClass and invokes its saySomething() method. Please note it can access all the data members and methods inside of nested static class.

DemoClass.java

package jcg.zheng.demo;

public class DemoClass {

	/**
	 * A static class must be created inside a class.
	 * 
	 * It can be accessed by outer class name. It can access static data members of
	 * outer class including private.
	 * 
	 * It cannot access non-static data members and methods.
	 *
	 * 
	 */
	static class DemoStaticClass {
		public DemoStaticClass(int someId) {
			super();
			this.someId = someId;
		}

		private static String message = "Static message inside a nested static class";
		
		private int someId;

		public String saySomething() {
			return instanceCount + " is from outer-class private static member.  " + message + " and " + someId;
		}

	}

	private static String commonMsg;

	// static members belong to the class, so it's not cleaned by the garbage
	// collection
	private static int instanceCount;

	// static block is executed during the class is loaded in memory
	static {
		instanceCount = 0;
	}

	// multiple static blocks are executed based on its order
	static {
		commonMsg = "Mary likes flowers";
	}

	public static int getInstanceCount() {
		return instanceCount;
	}

	private String name;

	public DemoClass(String name) {
		super();
		setName(name);

		instanceCount++;
	}

	public String getName() {
		return name;
	}

	public void sayHello() {
		DemoStaticClass demo = new DemoStaticClass(2);
		System.out.println(getName() + " " + demo.saySomething() + commonMsg);
	}

	public void setName(String name) {
		this.name = name;
	}

}
  • line 15 – create a nested static class
  • line 21, 31, 35 – create static data members
  • line 38, 43 – initialize static data member values
  • line 47 – create a static method
  • line 65 – create an object of a nested static class

3.3 DemoInterface

In this step, I will create DemoInterface which has two static members: one with a static keyword, the other doesn’t. It also has a static method. Interface does not allow a static block.

DemoInterface.java

package jcg.zheng.demo;

public interface DemoInterface {

	String defaultStaticV = "test";

	static String message = "I am awesome!";

	static String foo(String msg) {
		return "Static is useful! " + msg;
	}

}

3.4 Task

In this step, I will create a Task class which implements Runnable. It has a static count member.

Task.java

package jcg.zheng.demo;

public class Task implements Runnable {
	private static int count;
	
	private int taskId;

	public Task(int id) {
		this.taskId = id;
		count++;
	}

	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName() + " Task ID : " + this.taskId + " static " + count);
	}
}

4. JUnit Test

4.1 DemoClassTest

In this step, I will create DemoClassTest which has the following tests:

  • test_nested_static_class – creates an instance of DemoStaticClass and uses its saySomething method.
  • test_static_method – create 10 instances of DemoClass and prints out its static attribute – instanceCount
  • test_static_methods – repeatedly calling the static method 10 times and got the same result.

DemoClassTest.java

package jcg.zheng.demo;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.RepeatedTest;
import org.junit.jupiter.api.Test;

public class DemoClassTest {
	
	private DemoClass dClass;

	@Test
	public void test_static_method() {
		assertEquals(0, DemoClass.getInstanceCount());
		for (int i = 1; i < 10; i++) {
			dClass = new DemoClass("Mary" + i);
			assertEquals("Mary" + i, dClass.getName());
			assertEquals(i, DemoClass.getInstanceCount());

			dClass.sayHello();
		}
	}

	@RepeatedTest(10)
	public void test_static_methods() {
		assertEquals(0, DemoClass.getInstanceCount());
	}

	@Test
	public void test_nested_static_class() {
		DemoClass.DemoStaticClass nestedCls = new DemoClass.DemoStaticClass();
		assertEquals("0 instances of DemoClass.  Mary is great and Mary likes flowers", nestedCls.saySomething());
	}
}

Execute the tests and capture the output here.

Running jcg.zheng.demo.DemoClassTest
Mary1 1 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary2 2 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary3 3 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary4 4 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary5 5 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary6 6 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary7 7 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary8 8 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Mary9 9 is from outer-class private static member.  Static message inside a nested static class and 2Mary likes flowers
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.197 sec

4.2 DemoInterfaceTest

In this step, I will create DemoInterfaceTest which tests the two static members and a static method.

DemoInterfaceTest.java

package jcg.zheng.demo;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

public class DemoInterfaceTest {

	@Test
	public void test_static() {
		assertEquals("I am awesome!", DemoInterface.message);

		assertEquals("test", DemoInterface.defaultStaticV);

		assertEquals("Static is useful! test", DemoInterface.foo("test"));
	}

}

Execute tests and capture output.

Running jcg.zheng.demo.DemoInterfaceTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec

4.3 MultiThreadsTest

In this step, I will create a MultiThreadTest class which creates ten threads to execute the Task Runnable. You will see that the Task‘s static count value is not matching the total instance count.

MultiThreadsTest.java

package jcg.zheng.demo;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Test;

public class MultiThreadsTest {

	@Test
	public void test_multi_thread_on_static() {
		ExecutorService service = Executors.newFixedThreadPool(10);
		IntStream.range(0, 10).forEach(i -> service.submit(new Task(i)));
	}

}

Execute tests and capture output here.

pool-1-thread-9 Task ID : 8 static 10
pool-1-thread-8 Task ID : 7 static 10
pool-1-thread-7 Task ID : 6 static 8
pool-1-thread-2 Task ID : 1 static 4
pool-1-thread-6 Task ID : 5 static 8
pool-1-thread-5 Task ID : 4 static 10
pool-1-thread-1 Task ID : 0 static 4
pool-1-thread-10 Task ID : 9 static 10
pool-1-thread-4 Task ID : 3 static 7
pool-1-thread-3 Task ID : 2 static 4

As you seen here, the static instanceCount is not coordinating with the object count for each thread execution.

5. Java Static Keyword Summary

As you seen in this example, I demonstrated:

  • How to define and use a static member|method in a class and interface.
  • How the static block is executed in a class.
  • How to import static method from the Junit library.
  • How a multi-threads application may give you unexpected results when calling a static method.

Developer should be careful when creating a large size static variable as it’s not cleaned up by the garbage collector. Developer also considers when creating a static method as it’s not easy to write a unit test. Please read this article for pro and con on static methods.

6. Download the Source Code

Download
You can download the full source code of this example here: Java Static Keyword Example

Mary Zheng

Mary has graduated from Mechanical Engineering department at ShangHai JiaoTong University. She also holds a Master degree in Computer Science from Webster University. During her studies she has been involved with a large number of projects ranging from programming and software engineering. She works as a senior Software Engineer in the telecommunications sector where she acts as a leader and works with others to design, implement, and monitor the software solution.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button