Skip to main content
  1. Resources/
  2. Study Materials/
  3. Information & Communication Technology Engineering/
  4. ICT Semester 4/
  5. Java Programming (4343203)/

11 mins· ·
Milav Dabgar
Author
Milav Dabgar
Experienced lecturer in the electrical and electronic manufacturing industry. Skilled in Embedded Systems, Image Processing, Data Science, MATLAB, Python, STM32. Strong education professional with a Master’s degree in Communication Systems Engineering from L.D. College of Engineering - Ahmedabad.
Java Advanced Topics - Wrapper Classes & Command Line Arguments

Java Advanced Topics

Wrapper Classes, Command Line Arguments & Extended Concepts

Chapter 14: Supplementary Java Topics
Completing the comprehensive Java programming curriculum

Wrapper Classes in Java

What are Wrapper Classes?

Wrapper classes provide a way to use primitive data types as objects. They "wrap" primitive values in an object so they can be used where objects are required.

Primitive to Wrapper Mapping

Primitive TypeWrapper Class
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

Why Use Wrapper Classes?

  • Collections: Can store only objects, not primitives
  • Generics: Work only with objects
  • Utility Methods: Conversion, parsing, comparison methods
  • Null Values: Can represent null, primitives cannot
  • Synchronization: Can be used in synchronized collections

Basic Example


// Creating wrapper objects
Integer num1 = new Integer(10);  // Deprecated
Integer num2 = Integer.valueOf(20);  // Preferred
Integer num3 = 30;  // Autoboxing

// Converting back to primitive
int primitive = num1.intValue();  // Unboxing
int auto = num2;  // Auto-unboxing
                        

Autoboxing and Unboxing

Wrapper Classes Autoboxing Process

Autoboxing

Automatic conversion of primitive types to their corresponding wrapper class objects.


// Autoboxing examples
Integer num = 100;  // int to Integer
Double d = 3.14;    // double to Double
Boolean b = true;   // boolean to Boolean
Character c = 'A';  // char to Character

// In collections
List<Integer> numbers = new ArrayList<>();
numbers.add(10);    // Autoboxing: int to Integer
numbers.add(20);
numbers.add(30);

// In method calls
public void processNumber(Integer num) {
    System.out.println("Number: " + num);
}

processNumber(42);  // Autoboxing: int to Integer
                        

Unboxing

Automatic conversion of wrapper class objects to their corresponding primitive types.


// Unboxing examples
Integer num = new Integer(100);
int primitive = num;  // Integer to int

// In arithmetic operations
Integer a = 10;
Integer b = 20;
int sum = a + b;  // Both unboxed, then sum calculated

// In conditional statements
Boolean flag = Boolean.valueOf(true);
if (flag) {  // Boolean unboxed to boolean
    System.out.println("Flag is true");
}

// In array operations
Integer[] wrapperArray = {1, 2, 3, 4, 5};
int total = 0;
for (int value : wrapperArray) {  // Unboxing
    total += value;
}
                        

⚠️ Performance Consideration

Autoboxing/unboxing can impact performance in loops. Use primitives when possible for intensive operations.

Wrapper Class Utility Methods

Integer Class Methods


// Parsing strings to numbers
int num1 = Integer.parseInt("123");
int num2 = Integer.parseInt("1010", 2);  // Binary
int num3 = Integer.parseInt("FF", 16);   // Hexadecimal

// Creating Integer objects
Integer obj1 = Integer.valueOf(100);
Integer obj2 = Integer.valueOf("200");

// Conversion methods
String binary = Integer.toBinaryString(10);  // "1010"
String hex = Integer.toHexString(255);       // "ff"
String octal = Integer.toOctalString(8);     // "10"

// Comparison
Integer a = 100, b = 200;
int result = a.compareTo(b);  // -1 (a < b)

// Min/Max values
int maxInt = Integer.MAX_VALUE;  // 2147483647
int minInt = Integer.MIN_VALUE;  // -2147483648

// Utility methods
Integer.max(10, 20);  // Returns 20
Integer.min(10, 20);  // Returns 10
Integer.sum(10, 20);  // Returns 30
                        

Character Class Methods


// Character testing methods
char ch = 'A';
Character.isLetter(ch);      // true
Character.isDigit('5');      // true
Character.isWhitespace(' '); // true
Character.isUpperCase('A');  // true
Character.isLowerCase('a');  // true

// Character conversion
Character.toUpperCase('a');  // 'A'
Character.toLowerCase('Z');  // 'z'
Character.toString('X');     // "X"

// Numeric value
Character.getNumericValue('5');  // 5
Character.getNumericValue('A');  // 10 (hex)

// Creating Character objects
Character charObj = Character.valueOf('B');
                        

Boolean Class Methods


// Parsing strings to boolean
Boolean.parseBoolean("true");   // true
Boolean.parseBoolean("false");  // false
Boolean.parseBoolean("TRUE");   // true (case insensitive)

// Creating Boolean objects
Boolean b1 = Boolean.valueOf(true);
Boolean b2 = Boolean.valueOf("false");

// Logical operations
Boolean.logicalAnd(true, false);  // false
Boolean.logicalOr(true, false);   // true
Boolean.logicalXor(true, false);  // true

// Comparison
Boolean a = true, b = false;
a.compareTo(b);  // 1 (true > false)
                        

Command Line Arguments

What are Command Line Arguments?

Command line arguments are parameters passed to a Java program when it is executed from the command line. They are stored in the String array parameter of the main method.

Basic Example


// CommandLineExample.java
public class CommandLineExample {
    public static void main(String[] args) {
        System.out.println("Number of arguments: " + args.length);
        
        // Display all arguments
        for (int i = 0; i < args.length; i++) {
            System.out.println("Argument " + i + ": " + args[i]);
        }
        
        // Enhanced for loop
        System.out.println("\nAll arguments:");
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}
                        

Running the Program

java CommandLineExample Hello World 123

Output

Number of arguments: 3 Argument 0: Hello Argument 1: World Argument 2: 123 All arguments: Hello World 123

Practical Calculator Example


// Calculator.java
public class Calculator {
    public static void main(String[] args) {
        if (args.length != 3) {
            System.out.println("Usage: java Calculator   ");
            System.out.println("Example: java Calculator 10 + 5");
            return;
        }
        
        try {
            double num1 = Double.parseDouble(args[0]);
            String operator = args[1];
            double num2 = Double.parseDouble(args[2]);
            double result = 0;
            
            switch (operator) {
                case "+":
                    result = num1 + num2;
                    break;
                case "-":
                    result = num1 - num2;
                    break;
                case "*":
                case "x":
                    result = num1 * num2;
                    break;
                case "/":
                    if (num2 == 0) {
                        System.out.println("Error: Division by zero!");
                        return;
                    }
                    result = num1 / num2;
                    break;
                default:
                    System.out.println("Error: Invalid operator " + operator);
                    return;
            }
            
            System.out.println(num1 + " " + operator + " " + num2 + " = " + result);
            
        } catch (NumberFormatException e) {
            System.out.println("Error: Invalid number format!");
        }
    }
}
                        

Advanced Command Line Processing

File Processing Example


// FileProcessor.java
import java.io.*;
import java.util.Scanner;

public class FileProcessor {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage: java FileProcessor  [options]");
            System.out.println("Options:");
            System.out.println("  -c  Count lines");
            System.out.println("  -w  Count words");
            System.out.println("  -s  Show file size");
            return;
        }
        
        String filename = args[0];
        boolean countLines = false;
        boolean countWords = false;
        boolean showSize = false;
        
        // Process options
        for (int i = 1; i < args.length; i++) {
            switch (args[i]) {
                case "-c":
                    countLines = true;
                    break;
                case "-w":
                    countWords = true;
                    break;
                case "-s":
                    showSize = true;
                    break;
                default:
                    System.out.println("Unknown option: " + args[i]);
            }
        }
        
        processFile(filename, countLines, countWords, showSize);
    }
    
    private static void processFile(String filename, boolean countLines, 
                                  boolean countWords, boolean showSize) {
        try {
            File file = new File(filename);
            
            if (!file.exists()) {
                System.out.println("File not found: " + filename);
                return;
            }
            
            if (showSize) {
                System.out.println("File size: " + file.length() + " bytes");
            }
            
            if (countLines || countWords) {
                Scanner scanner = new Scanner(file);
                int lineCount = 0;
                int wordCount = 0;
                
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();
                    lineCount++;
                    if (countWords) {
                        String[] words = line.trim().split("\\s+");
                        if (!line.trim().isEmpty()) {
                            wordCount += words.length;
                        }
                    }
                }
                scanner.close();
                
                if (countLines) {
                    System.out.println("Lines: " + lineCount);
                }
                if (countWords) {
                    System.out.println("Words: " + wordCount);
                }
            }
            
        } catch (FileNotFoundException e) {
            System.out.println("Error reading file: " + e.getMessage());
        }
    }
}
                        

Configuration-Based Application


// ConfigApp.java
public class ConfigApp {
    private static String host = "localhost";
    private static int port = 8080;
    private static boolean debug = false;
    private static String logLevel = "INFO";
    
    public static void main(String[] args) {
        parseArguments(args);
        
        System.out.println("Application Configuration:");
        System.out.println("Host: " + host);
        System.out.println("Port: " + port);
        System.out.println("Debug: " + debug);
        System.out.println("Log Level: " + logLevel);
        
        // Start application with configuration
        startApplication();
    }
    
    private static void parseArguments(String[] args) {
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "--host":
                case "-h":
                    if (i + 1 < args.length) {
                        host = args[++i];
                    }
                    break;
                case "--port":
                case "-p":
                    if (i + 1 < args.length) {
                        try {
                            port = Integer.parseInt(args[++i]);
                        } catch (NumberFormatException e) {
                            System.err.println("Invalid port number: " + args[i]);
                        }
                    }
                    break;
                case "--debug":
                case "-d":
                    debug = true;
                    break;
                case "--log-level":
                case "-l":
                    if (i + 1 < args.length) {
                        logLevel = args[++i].toUpperCase();
                    }
                    break;
                case "--help":
                    showHelp();
                    System.exit(0);
                    break;
                default:
                    System.err.println("Unknown argument: " + args[i]);
            }
        }
    }
    
    private static void showHelp() {
        System.out.println("Usage: java ConfigApp [options]");
        System.out.println("Options:");
        System.out.println("  -h, --host         Set host (default: localhost)");
        System.out.println("  -p, --port         Set port (default: 8080)");
        System.out.println("  -d, --debug              Enable debug mode");
        System.out.println("  -l, --log-level   Set log level (default: INFO)");
        System.out.println("  --help                   Show this help");
    }
    
    private static void startApplication() {
        System.out.println("Starting application...");
        // Application logic here
    }
}
                        

Inner Classes - Detailed Coverage

Inner Classes Hierarchy and Types

Regular Inner Classes


// OuterClass.java
public class OuterClass {
    private String outerField = "Outer Field";
    
    // Regular inner class
    public class InnerClass {
        private String innerField = "Inner Field";
        
        public void display() {
            System.out.println("Outer field: " + outerField);
            System.out.println("Inner field: " + innerField);
            
            // Can access outer class methods
            outerMethod();
        }
    }
    
    private void outerMethod() {
        System.out.println("Outer method called");
    }
    
    public void createInner() {
        InnerClass inner = new InnerClass();
        inner.display();
    }
    
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.createInner();
        
        // Creating inner class from outside
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.display();
    }
}
                        

Method Local Inner Classes


public class MethodLocalExample {
    private String outerField = "Outer";
    
    public void methodWithInnerClass() {
        final String localVar = "Local Variable";
        
        // Method local inner class
        class LocalInnerClass {
            public void display() {
                System.out.println("Outer field: " + outerField);
                System.out.println("Local variable: " + localVar);
            }
        }
        
        LocalInnerClass local = new LocalInnerClass();
        local.display();
    }
    
    public static void main(String[] args) {
        MethodLocalExample example = new MethodLocalExample();
        example.methodWithInnerClass();
    }
}
                        

Static Nested Classes


public class OuterClass {
    private static String staticField = "Static Field";
    private String instanceField = "Instance Field";
    
    // Static nested class
    public static class StaticNestedClass {
        public void display() {
            // Can access static members of outer class
            System.out.println("Static field: " + staticField);
            
            // Cannot directly access instance members
            // System.out.println(instanceField); // Compilation error
            
            // Need outer class instance to access instance members
            OuterClass outer = new OuterClass();
            System.out.println("Instance field: " + outer.instanceField);
        }
    }
    
    public static void main(String[] args) {
        // Creating static nested class instance
        OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
        nested.display();
    }
}
                        

Anonymous Inner Classes


interface Greeting {
    void sayHello();
}

public class AnonymousExample {
    public static void main(String[] args) {
        // Anonymous inner class implementing interface
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("Hello from anonymous class!");
            }
        };
        
        greeting.sayHello();
        
        // Anonymous inner class extending class
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("Running in anonymous thread class");
            }
        };
        
        thread.start();
        
        // Using lambda (Java 8+) - modern alternative
        Greeting lambdaGreeting = () -> System.out.println("Hello from lambda!");
        lambdaGreeting.sayHello();
    }
}
                        

Garbage Collection in Detail

Garbage Collection Process and Memory Management

How Garbage Collection Works

Garbage Collection (GC) is Java's automatic memory management feature that reclaims memory used by objects that are no longer reachable.

Memory Areas

  • Young Generation: Where new objects are allocated
  • Old Generation: Long-lived objects
  • Permanent Generation: Class metadata (Java 7 and earlier)
  • Metaspace: Class metadata (Java 8+)

GC Process

  1. Mark: Identify which objects are still in use
  2. Sweep: Remove unmarked (unreachable) objects
  3. Compact: Defragment memory

// Objects eligible for garbage collection
public class GCExample {
    public static void main(String[] args) {
        // Creating objects
        String str1 = new String("Hello");
        String str2 = new String("World");
        
        // str1 becomes eligible for GC
        str1 = null;
        
        // Both str1 and str2 become eligible for GC
        str1 = str2 = null;
        
        // Suggesting GC (not guaranteed)
        System.gc();
        
        // Creating objects in loop
        for (int i = 0; i < 1000; i++) {
            String temp = new String("Temporary " + i);
            // temp becomes eligible for GC at end of each iteration
        }
    }
}
                        

Making Objects Eligible for GC


public class GCEligibility {
    
    // Method 1: Nullifying references
    public void nullifyReference() {
        String str = new String("Test");
        str = null; // Now eligible for GC
    }
    
    // Method 2: Reassigning references
    public void reassignReference() {
        String str1 = new String("First");
        String str2 = new String("Second");
        str1 = str2; // "First" object eligible for GC
    }
    
    // Method 3: Objects created in method scope
    public void methodScope() {
        String localStr = new String("Local");
        // localStr eligible for GC when method ends
    }
    
    // Method 4: Island of isolation
    class Node {
        Node next;
        String data;
        
        Node(String data) {
            this.data = data;
        }
    }
    
    public void islandOfIsolation() {
        Node node1 = new Node("Node1");
        Node node2 = new Node("Node2");
        
        node1.next = node2;
        node2.next = node1; // Circular reference
        
        node1 = null;
        node2 = null;
        // Both nodes eligible for GC despite circular reference
    }
}
                        

finalize() Method


public class FinalizeExample {
    private String name;
    
    public FinalizeExample(String name) {
        this.name = name;
    }
    
    // Called by GC before object destruction
    @Override
    protected void finalize() throws Throwable {
        System.out.println("Finalizing: " + name);
        // Cleanup operations can be performed here
        // But avoid relying on finalize() for critical cleanup
        super.finalize();
    }
    
    public static void main(String[] args) {
        FinalizeExample obj1 = new FinalizeExample("Object1");
        FinalizeExample obj2 = new FinalizeExample("Object2");
        
        obj1 = null;
        obj2 = null;
        
        System.gc(); // Request garbage collection
        
        try {
            Thread.sleep(1000); // Give GC time to run
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
                        

⚠️ Important Notes about finalize()

  • finalize() method is deprecated in Java 9+
  • Not guaranteed to be called
  • Can cause performance issues
  • Use try-with-resources or explicit cleanup methods instead

Summary: Advanced Java Topics

Wrapper Classes

  • Convert primitives to objects
  • Enable collection storage
  • Provide utility methods
  • Support autoboxing/unboxing
  • Essential for generics

Command Line Arguments

  • Pass parameters to programs
  • Configure application behavior
  • Process user input
  • Support scripting and automation
  • Enable flexible program execution

Inner Classes

  • Regular inner classes (instance-based)
  • Static nested classes (class-based)
  • Method local inner classes
  • Anonymous inner classes
  • Encapsulation and organization benefits

Garbage Collection

  • Automatic memory management
  • Mark-sweep-compact algorithm
  • Generational garbage collection
  • Object lifecycle management
  • Performance optimization

🎯 Learning Outcomes

You now understand the complete Java programming ecosystem including advanced memory management, flexible program configuration, and sophisticated class organization techniques that are essential for professional Java development.