The System
class in Java is a final class that provides several useful class fields and methods. It is part of the java.lang
package, which is automatically imported into every Java program. The System
class cannot be instantiated (Why ? due to private Constructor).
Among the facilities provided by the System
class are standard input, standard output, and error output streams; access to externally defined properties and environment variables; a means of loading files and libraries; and a utility method for quickly copying a portion of an array.
Key Features and Methods of System Class
- Standard Input, Output, and Error Streams
- Environment Properties and Variables
- System Properties
- Array Copying
- Current Time and Nanotime
- Garbage Collection
- Loading Files and Libraries
- Terminating the running JVM
Standard Input, Output, and Error Streams
System.in
: Standard input stream, typically linked to keyboard input.System.out
: Standard output stream, typically linked to console output.System.err
: Standard error output stream, typically linked to console output for error messages.
public class SystemExample {
public static void main(String[] args) {
System.out.println("This is standard output.");
System.err.println("This is standard error.");
}
}
Environment Properties and Variables
Environment variables are key-value pairs maintained by the operating system, which can affect the behavior of running processes. They are typically used to configure the runtime environment for applications.
Accessing Environment Variables : Environment variables can be accessed using System.getenv
.
public class EnvironmentVariablesExample {
public static void main(String[] args) {
// Getting a specific environment variable
String path = System.getenv("PATH");
System.out.println("PATH: " + path);
// Getting all environment variables
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.println(envName + " = " + env.get(envName));
}
}
}
System Properties
System properties are a set of key-value pairs that contain information about the runtime environment, including user details, JVM details, file paths, and more. These properties are accessible via the System
class.
System properties can be accessed using System.getProperty
and set using System.setProperty
.
public class SystemPropertiesExample {
public static void main(String[] args) {
// Getting a single system property
String userDir = System.getProperty("user.dir");
System.out.println("User Directory: " + userDir);
// Getting multiple system properties
System.out.println("OS Name: " + System.getProperty("os.name"));
System.out.println("Java Version: " + System.getProperty("java.version"));
// Setting a system property
System.setProperty("custom.property", "customValue");
System.out.println("Custom Property: " + System.getProperty("custom.property"));
// Listing all system properties
Properties properties = System.getProperties();
properties.list(System.out);
}
}
System properties are specific to the JVM instance, while environment variables are accessible by all processes running on the OS.
System properties can be modified at runtime using System.setProperty
, but environment variables cannot be changed at runtime within the JVM.
System properties are set by the JVM or user within the application, while environment variables are set by the operating system.
Array Copying
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
: Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array. If any array index is out of bounds, or if the length
is negative, an IndexOutOfBoundsException
will be thrown.
public class ArrayCopyExample {
public static void main(String[] args) {
int[] src = {1, 2, 3, 4, 5};
int[] dest = new int[5];
// Copy elements from src to dest
System.arraycopy(src, 0, dest, 0, src.length);
// Print the destination array
for (int i : dest) {
System.out.print(i + " ");
}
}
}
Current Time and Nanotime
The Java System
class provides methods to measure time with varying levels of precision. These methods are useful for tasks like benchmarking, profiling, and handling time-sensitive operations. The key methods for measuring time are currentTimeMillis
and nanoTime
.
System.currentTimeMillis()
returns the current time in milliseconds since the Unix epoch (January 1, 1970, 00:00:00 GMT).
public class CurrentTimeMillisExample {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
// Simulate some work with a sleep
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("Elapsed time in milliseconds: " + elapsedTime);
}
}
System.nanoTime()
returns the current value of the running Java Virtual Machine’s high-resolution time source, in nanoseconds.
public class NanoTimeExample {
public static void main(String[] args) {
long startTime = System.nanoTime();
// Simulate some work with a sleep
try {
Thread.sleep(1); // Sleep for 1 millisecond
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.nanoTime();
long elapsedTime = endTime - startTime;
System.out.println("Elapsed time in nanoseconds: " + elapsedTime);
}
}
Loading Files and Libraries
The Java System
class provides functionality to load files and native libraries dynamically at runtime. This is useful for scenarios where the files or libraries needed by the application are determined dynamically or may change over time.
System.load(String filename)
: this method loads a native library specified by the filename
argument.
public class LoadNativeLibraryExample {
public static void main(String[] args) {
try {
System.load("/path/to/library.so"); // Unix/Linux
System.load("C:\\path\\to\\library.dll"); // Windows
System.out.println("Library loaded successfully.");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native library not found: " + e);
}
}
}
Loading Libraries : System.loadLibrary(String libname)
: This method loads the native library specified by the libname
argument. The JVM searches for the library in the directories specified by the java.library.path
system property.
public class LoadLibraryExample {
static {
System.loadLibrary("myLibrary");
}
public native void myNativeMethod();
public static void main(String[] args) {
LoadLibraryExample example = new LoadLibraryExample();
example.myNativeMethod();
}
}
Loading Resources
: ClassLoader.getResource(String name)
: This method finds the resource with the given name. The name is a pathname that is interpreted relative to the classpath.
public class LoadResourceExample {
public static void main(String[] args) {
// Load a resource from the classpath
URL resource = LoadResourceExample.class.getClassLoader().getResource("file.txt");
if (resource != null) {
try {
InputStream inputStream = resource.openStream();
// Read from inputStream
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.err.println("Resource not found.");
}
}
}
Garbage Collection
The Java System
class provides a method gc()
that suggests the Java Virtual Machine (JVM) to perform garbage collection. Garbage collection is an automatic memory management process in Java that reclaims memory occupied by objects that are no longer in use, making it available for reuse by the application.
However, the JVM is not obligated to honor this request. It is merely a suggestion, and the JVM decides whether to perform garbage collection based on various factors such as the current heap size, available memory, and garbage collection algorithm in use.
public class FinalizeExample {
public void finalize() {
// Cleanup code goes here
System.out.println("Object is being finalized.");
}
public static void main(String[] args) {
FinalizeExample obj = new FinalizeExample();
obj = null; // Making the object eligible for garbage collection
System.gc(); // Requesting garbage collection
}
}
It’s generally not recommended to call System.gc()
explicitly in application code because:
- The JVM’s garbage collector is designed to run automatically and efficiently manage memory without manual intervention.
- Explicitly calling
System.gc()
can introduce unnecessary overhead and affect the performance of the application.
Terminating the running JVM
In Java, the System
class provides a method called exit(int status)
that allows you to terminate the currently running Java Virtual Machine (JVM). This method is commonly used to abruptly halt the execution of a Java program.
The exit(int status)
method terminates the currently running JVM with the specified status code. The status code is an integer value that indicates the reason for termination. A status code of 0 typically indicates successful termination, while non-zero values indicate some kind of error or abnormal termination.
public class ExitExample {
public static void main(String[] args) {
System.out.println("Before exit");
System.exit(0); // Terminate JVM with status code 0
System.out.println("After exit"); // This line will not be executed
}
}
public class ShutdownHookExample {
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("Cleanup tasks before JVM exit...");
// Perform cleanup tasks here
}));
// Simulating program execution
System.out.println("Program execution started.");
try {
Thread.sleep(2000); // Simulate some work
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Program execution completed.");
// Terminate JVM with status code 0
System.exit(0);
}
}