Exceptions, Generics, and Collections in Java
Class: CSCE-314
Notes:
Knowledge Check 8 Q2:
Which of the following statements best describes the Java Virtual Machine (JVM)?
- The JVM compiles Java source code into machine code and provides platform independence by executing bytecode on different operating systems.
- The JVM converts Java bytecode into native machine code at runtime using Just-In-Time (JIT) compilation and supports automatic garbage collection for memory management.
- The JVM is responsible for compiling Java source code directly into native machine code, enabling Java to run without the need for a runtime environment.
- The JVM supports platform independence by directly executing machine code, while also providing security and sandboxing through the operating system’s kernel.
Learning Goals: Learn exception handling, generics, collections, and command-line arguments in Java.
1. Why We Need Exceptions
In Java, exceptions provide a structured way to handle unexpected events or errors without crashing the program.
public class DivideExample {
public static void main(String[] args) {
int a = 10, b = 0;
try {
int result = a / b;
System.out.println("Result = " + result);
} catch (ArithmeticException e) {
System.out.println("Error: Cannot divide by zero!");
} finally {
System.out.println("Done dividing.");
}
}
}
- If you do a
tryyou have to have either acatchor afinally. - If there is a
finally, you will always do thefinally, whether an error is caught or not.
2. Throwing Your Own Exceptions
You can throw an exception to indicate an error condition that your method detects.
public class NegativeBalanceException extends Exception {
public NegativeBalanceException(String message) {
super(message);
}
}
public class BankAccount {
private double balance;
public void withdraw(double amount) throws NegativeBalanceException {
if (amount > balance) {
throw new NegativeBalanceException("Insufficient funds!");
}
balance -= amount;
}
}
public static void main(String[] args) {
BankAccount acct = new BankAccount();
try {
acct.withdraw(100);
} catch (NegativeBalanceException e) {
System.out.println("Withdrawal failed: " + e.getMessage());
}
}
- You have to define your exception as a public class that extends the
Exceptionclass.
3. Introducing Generics
Generics let us write code that works with many types while remaining type-safe and reusable.
- We want to be able to write code that will work with different types without having to write it over and over with different type signatures.
public class Box<T> {
private T value;
public void set(T value) { this.value = value; }
public T get() { return value; }
@Override
public String toString() {
return "Box holds: " + value;
}
}
public class TestBox {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
Box<String> strBox = new Box<>();
intBox.set(42);
strBox.set("CSCE314");
System.out.println(intBox);
System.out.println(strBox);
}
}
- Note how we are defining a generic type
T - Whatever
Tis it will be that in all of the definitions. - Note we need to specify
Twithin<>for both definition and calling of the class
4. Generic Methods
A method can also be generic, even inside a non-generic class.
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] nums = {1, 2, 3};
String[] names = {"Alice", "Bob"};
printArray(nums);
printArray(names);
}
5. The Java Collections Framework
Java’s java.util package includes powerful data structures built on generics.
List example
import java.util.*;
// ArrayList example (1st form of collection)
public class ListExample {
public static void main(String[] args) {
List<String> students = new ArrayList<>();
students.add("Maya");
students.add("John");
students.add("Priya");
System.out.println("Class list: " + students);
students.remove("John");
System.out.println("After removal: " + students);
}
}
// HashSet example (2nd form of collection)
Set<String> majors = new HashSet<>();
majors.add("CS");
majors.add("CE");
majors.add("CS"); // ignored
System.out.println("Unique majors: " + majors);
// HashMap example (3rd form of collection)
Map<String, String> contacts = new HashMap<>();
contacts.put("Alice", "alice@tamu.edu");
contacts.put("Bob", "bob@tamu.edu");
System.out.println("Bob's email: " + contacts.get("Bob"));
- Java provides us with the following forms of collections:
ArrayListHashSetHashMap- Like haskell tuples
6. Command-Line Arguments
Java programs can receive input directly from the command line using the String[] args parameter.
public class ArgsDemo {
public static void main(String[] args) {
System.out.println("Number of arguments: " + args.length);
for (int i = 0; i < args.length; i++) {
System.out.println("Arg " + i + ": " + args[i]);
}
}
}
Example run:
javac ArgsDemo.java
java ArgsDemo input.txt output.txt
Output:
Number of arguments: 2
Arg 0: input.txt
Arg 1: output.txt
File processor example:
public class FileProcessor {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: java FileProcessor <input>
<output>");
return;
}
String inputFile = args[0];
String outputFile = args[1];
System.out.println("Input file: " + inputFile);
System.out.println("Output file: " + outputFile);
// Later, we can open these files for reading/writing.
}
}
7. Summary of Key Concepts
- Exceptions handle runtime errors gracefully.
- Custom exceptions make code self-documenting.
- Generics enable type-safe, reusable components.
- Collections provide powerful data structures for managing objects.
- Command-line arguments allow flexible program input.
Further Reading in Java Java Java (Lam & Martin, 4th Ed.)
- Chapter 12 – Handling Exceptions (Sections 12.1–12.4)
- Chapter 13 – Generic Programming (Sections 13.1–13.5)
- Chapter 14 – Collections Framework (Sections 14.1–14.6)
- Chapter 10 – Program Input and Output (Section 10.2 for command-line arguments)