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

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

Unit 3: Intermediate Java Concepts & Application Development


Advanced Object-Oriented Programming Review & Patterns

Interfaces vs. Abstract Classes

Feature Interface Abstract Class
Purpose Define a contract (what) Provide a base (what + partial how)
Inheritance Multiple inheritance allowed (implements multiple) Single inheritance only (extends)
Methods public abstract by default (Java 8+ allows default/static) Can have abstract and concrete methods
Variables public static final (constants only) Any access modifier; can be non-final
Constructor No constructors Can have constructors (called via super())

[!TIP] When to Use

  • Interface: For defining capabilities across unrelated classes (e.g., Runnable, Serializable). Use when you need multiple inheritance of type.
  • Abstract Class: For sharing common code among closely related classes (e.g., AbstractList). Use when you have a base template with shared state/behavior.

Polymorphism

  • Method Overriding: Subclass provides specific implementation for a method declared in its superclass.

    • Rules: Same method name, parameters, return type (or covariant), access cannot be more restrictive.
  • Dynamic Method Dispatch: Runtime resolution of overridden method call based on the actual object type, not reference type.

    
    Animal a = new Dog(); // Animal reference, Dog object
    
    a.makeSound(); // Calls Dog's makeSound() at runtime
    
    

Design Patterns (Conceptual)

  • Singleton: Ensure a class has only one instance & provide global access.

    
    public class Singleton {
    
        private static Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
    
            if (instance == null) {
    
                instance = new Singleton();
    
            }
    
            return instance;
    
        }
    
    }
    
    

    Key: Private constructor, static instance, synchronized getInstance() for thread safety (or use eager initialization/static inner class).

  • Factory: Create objects without specifying exact class.

    
    interface Shape { void draw(); }
    
    class Circle implements Shape { public void draw() { /*...*/ } }
    
    class Factory {
    
        public Shape getShape(String shapeType) {
    
            if ("CIRCLE".equals(shapeType)) return new Circle();
    
            // ...
    
        }
    
    }
    
    

Exception Handling

Exception Hierarchy


Throwable

├── Error (system-level, e.g., OutOfMemoryError - not handled)

└── Exception

    ├── RuntimeException (unchecked, e.g., NullPointerException)

    └── Checked Exceptions (must be handled/declared, e.g., IOException)

try-catch-finally Syntax & Flow


try {

    // Code that may throw exception

} catch (SpecificException e) {

    // Handle specific exception

} catch (Exception e) {

    // Handle general exception (last)

} finally {

    // Always executes (even if return/catch), for cleanup

}

[!TIP] Best Practices

  • Catch most specific exception first.
  • finally for closing resources (but prefer try-with-resources).
  • Avoid empty catch blocks.
  • Do not catch Throwable/Error unless absolutely necessary.

throw vs. throws

  • throw: Used inside a method to raise an exception.

    
    throw new IllegalArgumentException("Invalid age");
    
    
  • throws: Used in method signature to declare exceptions that method might throw.

    
    public void readFile() throws IOException { ... }
    
    

Custom Exception Class


class MyException extends Exception { // or RuntimeException

    public MyException(String message) {

        super(message);

    }

}

Try-with-resources (for AutoCloseable)


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

    // Use br

} catch (IOException e) { ... }

// br.close() called automatically

\boxed{\text{Resources must implement } \texttt{AutoCloseable}}


Collections Framework & Generics

Core Interfaces & Primary Implementations

Interface Ordered? Duplicates? Nulls? Common Implementations
List Yes (index) Yes Yes (except Vector) ArrayList, LinkedList
Set No No At most one null HashSet, TreeSet
Queue Yes (FIFO) Yes Varies LinkedList, PriorityQueue
Map No (key-value) Keys: No, Values: Yes One null key, multiple null values HashMap, TreeMap

Iteration Methods

  1. Enhanced for loop: for (String s : list) { ... }

  2. Iterator: Iterator<E> it = list.iterator(); while(it.hasNext()) { E e = it.next(); }

    • Allows remove() during iteration.
  3. ListIterator (for List only): Bidirectional (hasPrevious(), previous()), allows add()/set().

Sorting: Comparable vs. Comparator

  • Comparable<T>: Natural ordering. Implemented by the class itself.

    
    class Student implements Comparable<Student> {
    
        public int compareTo(Student s) { return this.id - s.id; }
    
    }
    
    Collections.sort(list); // Uses natural order
    
    
  • Comparator<T>: External ordering. Separate class or lambda.

    
    Comparator<Student> byName = (s1, s2) -> s1.name.compareTo(s2.name);
    
    list.sort(byName); // or Collections.sort(list, byName)
    
    

Generics

  • Type Parameters: <T> in class/interface/method declaration.

  • Raw Types: Using generic class without type parameter (e.g., List list = new ArrayList();) — unsafe, generates warnings.

  • Wildcards:

    • ? : Unknown type.

    • ? extends T : Upper bound (T or subtype). Read-only (covariant).

    • ? super T : Lower bound (T or supertype). Write-only (contravariant).

    PECS: Producer extends, Consumer super.

  • Type Erasure: Generic type info removed at compile time; replaced with bounds/Object. No reification.


Java I/O Streams

Byte vs. Character Streams

Byte Streams Character Streams
For binary data (images, audio) For text data (Unicode)
Classes: InputStream, OutputStream Classes: Reader, Writer
Subclasses: FileInputStream, BufferedInputStream Subclasses: FileReader, BufferedReader, PrintWriter

Common Classes & Usage

  • File class: new File("path") — check existence (exists()), is directory (isDirectory()), list files (listFiles()).

  • BufferedReader/BufferedWriter: Buffered I/O for efficiency. readLine() for reading lines.

  • PrintWriter: Convenient print(), println(). Can wrap other writers/streams.

Object Serialization & Deserialization

  • Serializable: Marker interface (no methods). Class must implement it.

  • ObjectOutputStream / ObjectInputStream:

    
    try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.obj"))) {
    
        oos.writeObject(object);
    
    }
    
    // Deserialization:
    
    Object obj = ois.readObject();
    
    

    Note: transient fields are not serialized. serialVersionUID for version control.


Multithreading & Concurrency Basics

Thread Creation

  1. Extend Thread: Override run(). new MyThread().start();

  2. Implement Runnable: Pass to Thread constructor. Preferred (allows extending other classes).

    
    Thread t = new Thread(() -> { /* task */ });
    
    

Thread Lifecycle States

NEW → RUNNABLE (executing or ready) → BLOCKED/WAITING/TIMED_WAITING → TERMINATED

Synchronization

  • Intrinsic Lock (Monitor): Each object has one.

  • Synchronized Method: public synchronized void method() { ... } — locks this (or Class object for static).

  • Synchronized Block: Finer-grained control.

    
    synchronized(lockObject) {
    
        // critical section
    
    }
    
    

Inter-thread Communication (must own lock, call from synchronized context)

  • obj.wait(): Releases lock, enters WAITING.

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

  • obj.notifyAll(): Wakes all waiting threads.

java.util.concurrent Intro

  • ExecutorService: Manages a pool of threads.

    
    ExecutorService exec = Executors.newFixedThreadPool(2);
    
    exec.submit(() -> task());
    
    exec.shutdown();
    
    
  • Future<T>: Represents result of async computation.

    
    Future<Integer> f = exec.submit(() -> compute());
    
    int result = f.get(); // blocks until done
    
    

Graphical User Interface (GUI) with Swing

Swing vs. AWT

  • Swing: Lightweight (pure Java), pluggable look-and-feel, more components.

  • AWT: Heavyweight (native peers), platform-dependent.

Top-level Containers

  • JFrame: Main window (has content pane).

  • JDialog: Popup window.

  • JApplet (deprecated), JWindow.

Common Components

  • JLabel, JButton, JTextField, JTextArea (with JScrollPane),

  • JCheckBox, JRadioButton (in ButtonGroup), JComboBox, JList.

Layout Managers

Layout Description
FlowLayout Left-to-right, wraps. Default for JPanel.
BorderLayout North, South, East, West, Center. Default for JFrame content pane.
GridLayout Uniform grid (rows x cols).
GridBagLayout Flexible grid with constraints (complex).

Event Handling

  • Listener Interfaces: ActionListener (buttons, menu items), ItemListener (checkboxes, radio buttons), WindowListener (window events).

  • Adapter Classes: Provide empty implementations (e.g., WindowAdapter) so you override only needed methods.

    
    frame.addWindowListener(new WindowAdapter() {
    
        public void windowClosing(WindowEvent e) {
    
            System.exit(0);
    
        }
    
    });
    
    

Menus


JMenuBar menuBar = new JMenuBar();

JMenu fileMenu = new JMenu("File");

JMenuItem exitItem = new JMenuItem("Exit");

fileMenu.add(exitItem);

menuBar.add(fileMenu);

frame.setJMenuBar(menuBar);


Database Connectivity (JDBC)

JDBC Architecture


Java App → JDBC API → JDBC Driver → Database

  • DriverManager: Manages drivers, creates Connection.

  • Connection: Session with DB. Creates Statements.

  • Statement: Executes SQL. executeQuery() (SELECT), executeUpdate() (INSERT/UPDATE/DELETE).

  • ResultSet: Tabular data. next(), getXxx(column).

  • PreparedStatement: Precompiled SQL with parameters (?). Prevents SQL injection.

  • CallableStatement: Calls stored procedures.

Basic Connection & Query (MySQL Example)


String url = "jdbc:mysql://localhost:3306/db";

String user = "root", pass = "password";

try (Connection con = DriverManager.getConnection(url, user, pass);

     PreparedStatement pst = con.prepareStatement("INSERT INTO users(name) VALUES(?)")) {

    pst.setString(1, "Alice");

    int rows = pst.executeUpdate();

} catch (SQLException e) { e.printStackTrace(); }

Transaction Management


con.setAutoCommit(false); // Start transaction

try {

    // multiple statements

    con.commit(); // success

} catch (SQLException e) {

    con.rollback(); // failure

} finally {

    con.setAutoCommit(true);

}

Modern Java Features (Post-Java 8)

Lambda Expressions

  • Syntax: (parameters) -> expression or (parameters) -> { statements; }

  • Functional Interfaces: Single abstract method (SAM). Examples:

    • Predicate<T>: test(T) → boolean

    • Consumer<T>: accept(T) → void

    • Function<T,R>: apply(T) → R

    • Supplier<T>: get() → T

    
    List<String> list = Arrays.asList("a", "bb", "ccc");
    
    list.forEach(s -> System.out.println(s)); // Consumer
    
    list.removeIf(s -> s.length() > 1); // Predicate
    
    

Method References

  • ClassName::staticMethod

  • instance::instanceMethod

  • ClassName::instanceMethod (first arg is receiver)

  • ClassName::new (constructor)

    
    list.forEach(System.out::println); // instead of s -> System.out.println(s)
    
    

Stream API

  • Obtain stream: collection.stream(), Arrays.stream(array), Stream.of(...).

  • Intermediate Ops (lazy, return Stream): filter, map, sorted, distinct, limit.

  • Terminal Ops (eager, return non-Stream): forEach, collect, reduce, count, min/max.

    
    int sum = list.stream()
    
                  .filter(s -> s.length() > 1)
    
                  .mapToInt(String::length)
    
                  .sum();
    
    List<String> filtered = list.stream()
    
                                .filter(s -> s.startsWith("a"))
    
                                .collect(Collectors.toList());
    
    

Optional<T>

  • Container object which may or may not contain non-null value.

  • Avoids NullPointerException.

    
    Optional<String> opt = Optional.ofNullable(str);
    
    String result = opt.orElse("default");
    
    opt.ifPresent(s -> System.out.println(s));
    
    

Development Tools & Best Practices

IDE Proficiency (IntelliJ IDEA / Eclipse)

  • Debugging: Set breakpoints, step over (F8), step into (F7), evaluate expression, watch variables.

  • Refactoring: Rename (Shift+F6), extract method, change signature.

Unit Testing with JUnit 5


import org.junit.jupiter.api.*;

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

class MyTest {

    @BeforeEach void init() { /* runs before each test */ }

    @AfterEach void cleanup() { /* runs after each test */ }

    @Test

    void testAddition() {

        assertEquals(4, Calculator.add(2, 2));

        assertTrue(condition);

        assertThrows(Exception.class, () -> method());

    }

}

Build Automation: Maven

  • POM.xml: Project Object Model. Declares dependencies, plugins, build config.

  • Commands: mvn compile, mvn test, mvn package, mvn install.

  • Dependency Example:

    
    <dependency>
    
        <groupId>junit</groupId>
    
        <artifactId>junit-jupiter</artifactId>
    
        <version>5.8.2</version>
    
        <scope>test</scope>
    
    </dependency>
    
    

Javadoc

  • Comments: /** ... */ with tags @param, @return, @throws.

  • Generate: javadoc MyClass.java or via IDE/Maven (mvn javadoc:javadoc).

Logging (SLF4J + Logback example)

  • SLF4J: Facade API. Logger logger = LoggerFactory.getLogger(ClassName.class);

  • Logback: Implementation. Configure via logback.xml.

    
    logger.info("Message");
    
    logger.error("Error", exception);
    
    

    Avoid System.out.println() for production logging.

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