Skip to content
AL-406 · Java Lab/Quick Revision Short Notes

Java Lab (AL-406) - Unit 2 Short Notes

1.0 Object-Oriented Programming (OOP) Fundamentals in Java

1.1 Classes and Objects

  • Class: Blueprint for objects. Contains fields (variables), methods, constructors.

  • Object: Instance of a class. Created using new keyword.

  • Instance variables: Belong to each object. Have default values (0, false, null).

  • Local variables: Declared inside methods. No default values; must be initialized before use.

  • this keyword: Refers to current object. Used to:

    • Access instance members when shadowed by local variables.

    • Call another constructor in same class (this(...)).

    • Pass current object as parameter.

[!TIP] Common Pitfall: Forgetting to initialize local variables causes compilation error.

1.2 Constructors

  • Default constructor: Provided by compiler if no constructor defined. Initializes instance variables to default values.

  • Parameterized constructor: Takes parameters to initialize fields.

  • Constructor overloading: Multiple constructors with different parameter lists.

  • Constructor cannot be static, final, abstract, or synchronized.

1.3 Methods

  • Method signature: Method name + parameter types (return type not part of signature).

  • Method overloading: Same method name, different parameters (compile-time polymorphism).

  • Parameter passing:

    • Primitives: Passed by value (copy).

    • Objects: Reference passed by value (copy of reference).

  • Return types: void (no return), primitives, objects.

1.4 Access Modifiers & Encapsulation

  • Access levels:

    | Modifier | Class | Package | Subclass | World | |----------|-------|---------|----------|-------| | public | ✓ | ✓ | ✓ | ✓ | | protected | ✓ | ✓ | ✓ | ✗ | | default (no modifier) | ✓ | ✓ | ✗ | ✗ | | private | ✓ | ✗ | ✗ | ✗ |

  • Encapsulation: Bundling data and methods, restricting direct access via private fields, providing public getters/setters.

  • Data hiding: Using private to hide internal state and expose controlled interface.

[!TIP] Exam Focus: Memorize the access modifier table. protected allows access to subclasses even in different packages.

1.5 Static Keyword

  • Static variables: Shared among all instances. Belong to class. Loaded when class is loaded.

  • Static methods: Can access only static members. Called using class name (e.g., Math.sqrt()).

  • Static blocks: Executed once when class is loaded. Used for static initialization.

  • main method: Must be public static void main(String[] args) to be JVM entry point. static so JVM can call without object.

1.6 Inheritance

  • extends keyword: Inherits from superclass. Single inheritance only (a class extends one class).

  • super keyword:

    • super(): Calls superclass constructor. Must be first statement in constructor.

    • super.member: Accesses superclass members (fields/methods) hidden by subclass.

  • Method overriding: Subclass provides specific implementation. Same signature (name, parameters, return type). Use @Override annotation (optional but recommended).

  • Object class: Root of all classes. Methods: toString(), equals(), hashCode(), getClass(), etc.

1.7 Polymorphism

  • Compile-time polymorphism: Method overloading.

  • Runtime polymorphism: Method overriding via dynamic method dispatch.

    • Reference type determines which methods are accessible at compile time.

    • Object type determines which overridden method is executed at runtime.

  • Example: Animal a = new Dog(); a.sound(); calls Dog.sound() if overridden.

1.8 Abstraction

  • Abstract class:

    • Declared with abstract. Can have abstract methods (no body) and concrete methods.

    • Cannot be instantiated.

    • Subclasses must implement all abstract methods unless subclass is also abstract.

  • Interface:

    • Pure abstraction (pre-Java 8). All methods implicitly public abstract. Variables public static final.

    • Classes implement interfaces. Multiple interfaces allowed.

    • Since Java 8: default and static methods allowed; since Java 9: private methods.

  • Differences:

    | Feature | Abstract Class | Interface | |---------|---------------|-----------| | Methods | Can have concrete and abstract | Abstract (plus default/static in Java 8+) | | Variables | Any access modifier | public static final (constants) | | Multiple inheritance | Not allowed (single inheritance) | Allowed (class can implement multiple interfaces) | | Constructor | Yes | No | | Access modifiers for methods | Any | public (implicitly) | | Implementation | Partial (some methods implemented) | Full (pre-Java 8) or partial (with default) |

[!TIP] Use abstract class when you have a base class with common code; use interface for defining contracts and multiple inheritance of type.

1.9 final Keyword

  • final variables: Constants. Once assigned, value cannot change. For objects, reference cannot change but object state may (if mutable).

  • final methods: Cannot be overridden.

  • final classes: Cannot be subclassed (e.g., String, Integer, Math).


2.0 Exception Handling

2.1 Exception Hierarchy

DiagramSEARCH: Java exception hierarchy diagram
  • Throwable: Root.

    • Error: Serious problems (e.g., OutOfMemoryError, StackOverflowError). Application should not catch.

    • Exception: Recoverable issues.

      • Checked exceptions: Subclasses of Exception but not RuntimeException. Must be handled or declared (e.g., IOException, SQLException).

      • Unchecked exceptions: Subclasses of RuntimeException (e.g., NullPointerException, ArrayIndexOutOfBoundsException). Not mandatory to handle.

2.2 Try-Catch-Finally


try {

    // code that may throw exception

} catch (ExceptionType1 e1) {

    // handle specific exception

} catch (ExceptionType2 e2) {

    // handle another

} finally {

    // always executes (except System.exit() or JVM crash). For cleanup (e.g., close resources).

}
  • Multiple catch blocks: Order from most specific to most general.

  • finally block executes even if return in try/catch.

  • Try-with-resources (Java 7+) automatically closes resources.

2.3 Common Exception Types

  • ArithmeticException: / by zero.

  • NullPointerException: Accessing instance members on null object.

  • ArrayIndexOutOfBoundsException: Invalid array index.

  • IndexOutOfBoundsException: General for collections (e.g., ArrayList).

  • NumberFormatException: Parsing invalid number string (e.g., Integer.parseInt("abc")).

  • IOException: General I/O failure.

  • ClassNotFoundException: Class not found at runtime.

  • IllegalArgumentException: Illegal argument passed to method.

2.4 throw and throws

  • throw: Manually throw an exception.

    
    if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    
    
  • throws: Declare exceptions that method might throw. Caller must handle or declare.

    
    public void readFile() throws IOException { ... }
    
    
  • throw always requires an exception object. throws is part of method signature.

2.5 Custom Exceptions

  • Create by extending Exception (for checked) or RuntimeException (for unchecked).

// Checked custom exception

class InsufficientFundsException extends Exception {

    public InsufficientFundsException(String msg) { super(msg); }

}
// Unchecked custom exception

class InvalidInputException extends RuntimeException {

    public InvalidInputException(String msg) { super(msg); }

}

[!TIP] Extend RuntimeException for unchecked to avoid forcing callers to handle.


3.0 Core Data Structures & Collections Framework

3.1 Collections Framework Overview

DiagramSEARCH: Java collections framework hierarchy
  • Collection interface (root for lists, sets, queues):

    • List: Ordered, allows duplicates (e.g., ArrayList, LinkedList).

    • Set: Unordered (except LinkedHashSet/TreeSet), no duplicates (e.g., HashSet, TreeSet).

    • Queue: FIFO (e.g., LinkedList, PriorityQueue).

  • Map interface: Key-value pairs. Keys unique, values may duplicate. Not a Collection.

    • Implementations: HashMap, LinkedHashMap, TreeMap, Hashtable.

3.2 List Interface

  • ArrayList:

    • Resizable array implementation.

    • Fast random access (get(i) O(1)).

    • Slow insert/delete in middle (shift elements O(n)).

    • Not synchronized (use Collections.synchronizedList for thread safety).

  • LinkedList:

    • Doubly-linked list.

    • Fast insert/delete at ends (O(1)), but get(i) O(n) (traversal).

    • Implements Deque (double-ended queue).

    • More memory per element (pointers).

  • Common methods: add(E e), add(int index, E e), get(int index), set(int index, E e), remove(int index), size(), clear(), contains(Object o).

Operation ArrayList LinkedList
Get by index O(1) O(n)
Add at end O(1) amortized O(1)
Add/remove in middle O(n) O(n) (but O(1) if have iterator at position)
Memory overhead Low (array) High (node objects + pointers)
Iteration Fast (cache-friendly) Slower (pointer chasing)

[!TIP] Use ArrayList for frequent reads, LinkedList for frequent insertions/removals at ends.

3.3 Set Interface

  • HashSet:

    • Uses hash table. Order not guaranteed (may change on rehash).

    • Allows one null.

    • Performance: O(1) avg for add/remove/contains.

    • Uses hashCode() and equals() for uniqueness.

  • LinkedHashSet:

    • HashSet subclass with insertion-order maintenance.

    • Slightly slower than HashSet; more memory (doubly-linked list).

  • TreeSet:

    • Sorted set (natural ordering or Comparator).

    • Red-Black tree. O(log n) for add/remove/contains.

    • No null elements (cannot compare null).

  • Common methods: add(E e), remove(Object o), contains(Object o), size(), iterator().

Feature HashSet LinkedHashSet TreeSet
Order None Insertion order Sorted (natural/comparator)
Null allowed Yes (one) Yes (one) No
Performance (add/contains) O(1) avg O(1) avg O(log n)
Underlying structure Hash table Hash table + linked list Red-Black tree

3.4 Map Interface

  • HashMap:

    • Key-value pairs. No duplicate keys.

    • Allows one null key and multiple null values.

    • Not synchronized (use Collections.synchronizedMap or ConcurrentHashMap for thread safety).

    • Order not guaranteed.

  • LinkedHashMap:

    • HashMap subclass with insertion-order or access-order (LRU) maintenance.
  • TreeMap:

    • Sorted map by keys (natural or Comparator).

    • No null keys.

  • Common methods:

    • put(K key, V value), get(Object key), remove(Object key), containsKey(Object key), containsValue(Object value).

    • keySet(), values(), entrySet() (for iteration).

3.5 Iterators & Enhanced For Loop

  • Iterator:

    • hasNext(): Returns true if more elements.

    • next(): Returns next element.

    • remove(): Removes last returned element (optional operation).

    • Fail-fast: Throws ConcurrentModificationException if collection modified after iterator creation (except via remove()).

  • ListIterator (for List only):

    • Bidirectional: hasPrevious(), previous().

    • Can add, set, remove while iterating.

  • Enhanced for loop (for-each):

    
    for (Element e : collection) { ... }
    
    for (int num : array) { ... }
    
    
    • Works with any Iterable (arrays, Collection, etc.).

    • Read-only; cannot modify collection (no add/remove).

    • Compiles to use Iterator.

[!TIP] Use Iterator.remove() to safely remove during iteration. Avoid for-each if you need to modify collection.


4.0 Input/Output (I/O) Operations

4.1 Streams, Readers, and Writers

  • Byte streams (InputStream, OutputStream): For binary data (images, audio).

  • Character streams (Reader, Writer): For text data. Handle character encoding (e.g., UTF-8). Prefer over byte streams for text.

4.2 File I/O with File Class

  • File represents file/directory path (may not exist).

  • Common methods:

    • exists(), isFile(), isDirectory().

    • length(), lastModified().

    • delete(), mkdir(), listFiles().

4.3 Reading/Writing Text Files

  • FileReader/FileWriter: Basic character streams. Not buffered; slow for many small reads/writes.

  • BufferedReader/BufferedWriter:

    • Buffered for efficiency. Reduce system calls.

    • BufferedReader.readLine() reads line by line (returns null at EOF).

  • PrintWriter:

    • Convenient print(), println(), format().

    • Can wrap other Writers (e.g., BufferedWriter).

    • Auto-flush option.

Example (reading):


try (BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {

    String line;

    while ((line = br.readLine()) != null) {

        System.out.println(line);

    }

} catch (IOException e) {

    e.printStackTrace();

}

Example (writing):


try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("output.txt")))) {

    pw.println("Hello");

    pw.printf("Value: %.2f", 3.14159);

}

4.4 try-with-resources

  • For classes implementing AutoCloseable (all I/O streams, readers, writers, Scanner, etc.).

  • Resources declared in try() are automatically closed at end of block (even if exception).

  • Multiple resources separated by ;.


try (BufferedReader br = new BufferedReader(new FileReader("file.txt"));

     PrintWriter pw = new PrintWriter("out.txt")) {

    // use br and pw

} catch (IOException e) {

    // handle

}
// br and pw automatically closed

[!TIP] Always use try-with-resources for I/O to prevent resource leaks. Order: close resources in reverse order of declaration.


5.0 Multithreading Basics

5.1 Introduction to Threads

  • Thread: Lightweight process. Enables concurrent execution.

  • Creating threads:

    1. Extend Thread class:

      
      class MyThread extends Thread {
      
          public void run() { ... }
      
      }
      
      new MyThread().start();
      
      
    2. Implement Runnable interface (preferred):

      
      class MyRunnable implements Runnable {
      
          public void run() { ... }
      
      }
      
      new Thread(new MyRunnable()).start();
      
      
    • Prefer Runnable because Java doesn't support multiple inheritance; allows task (Runnable) separate from thread mechanism.

5.2 Thread Lifecycle

DiagramSEARCH: Java thread lifecycle states
  • NEW: Thread created but start() not called.

  • RUNNABLE: Executing or ready to execute (includes running and runnable in OS scheduler).

  • BLOCKED: Waiting for monitor lock to enter synchronized block/method.

  • WAITING: Waiting indefinitely (e.g., wait(), join() without timeout).

  • TIMED_WAITING: Waiting with timeout (e.g., sleep(ms), wait(ms), join(ms)).

  • TERMINATED: Completed or died.

5.3 Thread Priorities & Methods

  • setPriority(int p): MIN=1, NORM=5, MAX=10. OS-dependent; not guaranteed.

  • getName(), getId().

  • start(): Starts thread, calls run() in new thread. Cannot call start() twice (throws IllegalThreadStateException).

  • run(): Entry point. If called directly, runs in current thread (no new thread).

  • sleep(long ms): Pauses current thread (static method). Throws InterruptedException.

  • join(): Waits for thread to die. Throws InterruptedException.

  • yield(): Hints to scheduler to pause current thread (rarely used).

  • isAlive(): Checks if thread is RUNNABLE, BLOCKED, WAITING, TIMED_WAITING.

5.4 Synchronization & Thread Safety

  • Race condition: Multiple threads accessing shared mutable data without synchronization.

  • Synchronized methods:

    
    public synchronized void increment() { count++; }
    
    
    • Lock on this for instance methods, on Class object for static methods.
  • Synchronized blocks: Fine-grained locking.

    
    synchronized (lockObject) {
    
        // critical section
    
    }
    
    
  • Reentrant: Thread can re-enter same synchronized method (no deadlock on same thread).

  • Volatile: Ensures visibility of changes across threads (but not atomicity).

5.5 Inter-Thread Communication

  • Must be called from synchronized context on same monitor object.

  • wait(): Releases lock and waits. Can be interrupted.

  • notify(): Wakes one waiting thread (arbitrary).

  • notifyAll(): Wakes all waiting threads.

  • Typical pattern:

    
    synchronized (obj) {
    
        while (condition) obj.wait(); // use loop to avoid spurious wakeups
    
        // proceed
    
        obj.notify(); // or notifyAll()
    
    }
    
    

[!TIP] Always call wait() in a loop checking condition to handle spurious wakeups. notifyAll() is safer than notify() to avoid missed signals.


6.0 String Manipulation & StringBuilder/StringBuffer

6.1 String Class Immutability

  • Immutable: Cannot change after creation. Any modification creates new String object.

  • Why immutable:

    • Security (class loading, network connections).

    • Caching hashcode (efficient HashMap keys).

    • Thread safety (no synchronization needed).

    • String pool (interning) saves memory.

  • Common methods:

    • length(), charAt(int), substring(int begin, int end).

    • concat(String), equals(Object), compareTo(String).

    • indexOf(char/String), lastIndexOf().

    • toLowerCase(), toUpperCase(), trim().

    • startsWith(), endsWith(), contains().

    • split(String regex), join(CharSequence, ...).

6.2 StringBuilder & StringBuffer

  • Mutable: Can modify without creating new object.

  • StringBuilder (Java 5+):

    • Not synchronized. Faster.

    • Use in single-threaded or when synchronization handled externally.

  • StringBuffer (legacy, Java 1.0):

    • Synchronized. Thread-safe but slower.

    • Use when multiple threads modify same instance.

  • Key methods: append(...), insert(int, ...), delete(int, int), replace(int, int, String), reverse(), capacity(), ensureCapacity(int).

  • Performance: For repeated concatenation (e.g., in loops), StringBuilder is ~10-100x faster than String concatenation (+).

[!TIP] In single-threaded code, always prefer StringBuilder over StringBuffer for performance. For string concatenation in loops, use StringBuilder explicitly.


7.0 Wrapper Classes & Autoboxing/Auto-unboxing

7.1 Primitive Wrappers

  • Classes: Byte, Short, Integer, Long, Float, Double, Character, Boolean.

  • Parsing static methods:

    • Integer.parseInt(String), Long.parseLong(String), Float.parseFloat(String), etc.

    • Character.getNumericValue(char).

  • Utility methods:

    • toString(): Primitive to String.

    • valueOf(String): Returns wrapper object (may use cache for Integer etc.).

    • xxxValue(): intValue(), doubleValue(), etc.

  • Constants: Integer.MAX_VALUE, MIN_VALUE, SIZE (bits), BYTES.

  • Caching: Integer caches -128 to 127. valueOf() uses cache; new Integer() does not.

7.2 Autoboxing & Auto-unboxing

  • Autoboxing: Automatic conversion from primitive to wrapper.

    
    Integer i = 10; // autoboxing int to Integer
    
    List<Integer> list = new ArrayList<>();
    
    list.add(5); // autoboxing int to Integer
    
    
  • Auto-unboxing: Automatic conversion from wrapper to primitive.

    
    Integer i = 10;
    
    int j = i; // auto-unboxing
    
    
  • Implications:

    • In collections, only objects allowed; autoboxing enables storing primitives.

    • Can cause NullPointerException if unboxing null:

      
      Integer i = null;
      
      int j = i; // NPE
      
      
    • == vs equals(): == compares references for objects (except cached values -128 to 127 may be same reference). Use equals() for value comparison.

      
      Integer a = 1000, b = 1000;
      
      System.out.println(a == b); // false (outside cache)
      
      Integer c = 100, d = 100;
      
      System.out.println(c == d); // true (within cache)
      
      

[!TIP] Always use .equals() to compare wrapper objects. Be cautious with null during unboxing.


8.0 Practical Lab Patterns & Common Pitfalls

8.1 Debugging Techniques in IDE

  • Breakpoints: Pause execution at specific line.

  • Stepping:

    • Step Into (F7): Enter method.

    • Step Over (F8): Execute current line, pause next.

    • Step Out (Shift+F8): Finish current method, pause at caller.

  • Watching variables: View current values; can evaluate expressions.

  • Call Stack: See method invocation hierarchy.

  • Conditional Breakpoints: Break only when condition true.

8.2 Common Compilation & Runtime Errors

  • Compilation errors:

    • Syntax errors (missing ;, }).

    • Type mismatches (e.g., assigning String to int).

    • Cannot find symbol (class/method/variable not declared/imported).

    • Incompatible types (e.g., int to Integer without autoboxing? Actually autoboxing handles, but mismatched generics).

  • Runtime errors:

    • NullPointerException: Calling method/accessing field on null.

    • ArrayIndexOutOfBoundsException / IndexOutOfBoundsException: Invalid index.

    • ClassNotFoundException: Class not in classpath (e.g., Class.forName("com.Unknown")).

    • NumberFormatException: Integer.parseInt("abc").

    • ArithmeticException: Division by zero.

    • IllegalArgumentException: Invalid argument (e.g., negative size).

    • InputMismatchException (Scanner): Token doesn't match expected type.

8.3 Code Organization for Lab Assignments

  • Packages: Use reverse-domain naming (e.g., com.rgpv.lab2). Group related classes.

  • main method: Include for testing. Use sample inputs/outputs. Can have multiple classes with main for different tests.

  • Comments:

    • Javadoc for classes/methods: /** Description */.

    • Inline comments for complex logic.

  • Structure:

    • One public class per file (unless nested).

    • Separate business logic from I/O where possible.

    • Use meaningful variable/method names.

  • Testing: Test edge cases: null, empty collections, zero, negative numbers, large inputs, boundary values.

[!TIP] Always validate inputs (e.g., check for null, negative numbers) and handle exceptions gracefully. Write modular code with small methods.

Go to where you left off?

Quick Add to Notes

Save questions, your own notes and screenshots into notes filed by unit. It takes a free account.

Create free account

Have an account? Log in