Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Comprehensive Guide to Java Core Concepts and Best Practices

Tech May 16 1

Java Core Concepts Overview

1. Primitive Types and Operators

Java maintains a distinction between primitive types and reference types. The eight primitives are: byte, short, int, long, float, double, char, and boolean. Operator precedence follows standard mathematical rules with some Java-specific behaviors.

Logical operators exhibit important short-circuit behavior:

  • && (logical AND) and || (logical OR) perform short-circuit evaluation
  • & and | evaluate both operands regardless of the first result
  • ^ (XOR) returns true only when operands differ
int valueA = 10; 
int valueB = 5; 
boolean result = (valueA > valueB) && (valueB++ > 0); 
// valueB becomes 6 due to short-circuit evaluation
boolean result2 = (valueA < valueB) & (valueB++ > 0); 
// valueB becomes 7 because both sides evaluate

2. String Handling and Immutability

The String class is immutable and marked as final. When concatenating strings, the JVM internally uses StringBuilder or StringBuffer for optimization.

String textOne = "Hello"; 
String textTwo = "Hello"; 
// Both reference the same object in the string pool 
String textThree = new String("Hello"); 
// Creates a new object on the heap 
System.out.println(textOne == textTwo); // true 
System.out.println(textOne == textThree); // false 
System.out.println(textOne.equals(textThree)); // true

StringBuilder is preferred for single-threaded environments due to its lack of synchronization overhead, while StringBuffer provides thread-safe operations.

3. Data Structures and Collections Framework

Java collections store only reference types. Primitives require their wrapper classes (Integer, Double, etc.).

ArrayList vs LinkedList:

  • ArrayList uses a dynamic array with O(1) random access but O(n) insertion/deletion
  • LinkedList uses doubly-linked nodes with O(1) insertion/deletion but O(n) access

HashMap Internal Mechanics:

HashMap uses an array of buckets combined with linked lists (and red-black trees since Java 8 when threshold exceeds 8). The default initial capacity is 16 with a load factor of 0.75, triggering resize at 12 elements.

HashMap scores = new HashMap<>(); 
scores.put("Alice", 95); 
scores.put("Bob", 87); 
// Allows one null key and multiple null values 
// Not thread-safe - use ConcurrentHashMap for multi-threaded access

HashSet: Guarantees uniqueness through hashCode() and equals() methods. Ordering is not preserved.

TreeSet: Maintains sorted order using a red-black tree structure.

4. Access Modifiers and Scope

Java provides four access levels:

  • public: Accessible from anywhere
  • protected: Accessible within the same package and subclasses
  • default (package-private): Accessible only within the same package
  • private: Accessible only within the declaring class

5. Key Keywords and Their Usage

final:

  • Classes: Cannot be extended
  • Methods: Cannot be overridden
  • Variables: Cannot be reassigned (references cannot change, but object contents can)
final StringBuilder builder = new StringBuilder("Initial"); 
builder.append(" text"); // Allowed - modifying object contents 
// builder = new StringBuilder("New"); // Compilation error

static: Belongs to the class rather than instances. Static blocks execute during class loading.

volatile: Ensures visibility across threads but does not guarantee atomicity. Suitable for flags and status indicators.

synchronized: Provides mutual exclusion and visibility. Can lock on instance (non-static methods) or class (static methods) objects.

6. Object-Oriented Programming Principles

Encapsulation: Hiding internal state and requiring all interaction through methods. Use private fields with public getters/setters.

Inheritance: Use extends keyword. Constructor chaining occurs implicitly with super() call.

class Vehicle { 
    protected String brand; 
    public Vehicle(String brand) { 
        this.brand = brand; 
    } 
} 
class Car extends Vehicle { 
    private int wheels; 
    public Car(String brand, int wheels) { 
        super(brand); // Must be first statement 
        this.wheels = wheels; 
    } 
}

Polymorphism: Parent references can point to child objects. Method calls resolve at runtime (dynamic dispatch).

Vehicle myCar = new Car("Toyota", 4); 
myCar.display(); // Calls Car's overridden method if present 
// myCar.getWheels(); // Compilation error - Vehicle doesn't have this method 
Car specificCar = (Car) myCar; // Downcasting required

Abstract Classes vs Interfaces:

FeatureAbstract ClassInterface
ConstructorsYesNo
Instance fieldsYesOnly constants (public static final)
Multiple inheritanceNoYes (implements multiple)
Default methodsRegular methodsSince Java 8 (default keyword)
Static methodsYesSince Java 8
Private methodsYesSince Java 9

7. Exception Handling Architecture

Throwable is the parent class for all errors and exceptions:

  • Error: Serious problems like OutOfMemoryError, StackOverflowError - not meant to be caught
  • Exception: Recoverable conditions that programs should handle
  • RuntimeException: Unchecked exceptions (NullPointerException, ArrayIndexOutOfBoundsException)
  • Checked Exceptions: Must be declared or caught (IOException, SQLException)
try { 
    FileReader reader = new FileReader("config.txt"); 
    // Potentially risky operation 
} catch (FileNotFoundException e) { 
    System.err.println("Configuration file missing"); 
} catch (IOException e) { 
    System.err.println("Error reading file"); 
} finally { 
    // Always executes - cleanup resources 
    // Executes before any return statement in try/catch 
}

Exception matching proceeds from most specific to most general. A finally block always executes unless System.exit() is called.

8. Integer Caching Mechanism

Integer.valueOf() caches values between -128 and 127:

Integer numA = 100; 
Integer numB = 100; 
System.out.println(numA == numB); // true (cached) 
Integer numC = 200; 
Integer numD = 200; 
System.out.println(numC == numD); // false (outside cache range) 
System.out.println(numC.equals(numD)); // true (proper comparison)

9. Memory Management

Stack: Stores primitive values and object references. Method calls create stack frames.

Heap: Stores objects and arrays. Garbage collected when no references remain.

Method Area: Stores class metadata, static variables, and constant pool.

Object creation memory flow:

  1. Memory allocated on heap
  2. Instance variables initialized to defaults
  3. Explicit initialization and constructor execution
  4. Reference assigned to variable

10. Multithreading Fundamentals

Thread creation approaches:

// Approach 1: Extend Thread class 
class WorkerThread extends Thread { 
    public void run() { 
        System.out.println("Thread executing: " + Thread.currentThread().getName()); 
    } 
} 
// Approach 2: Implement Runnable interface (preferred) 
class TaskRunner implements Runnable { 
    public void run() { 
        System.out.println("Task running in: " + Thread.currentThread().getName()); 
    } 
} 
Thread t1 = new WorkerThread(); 
t1.start(); 
Thread t2 = new Thread(new TaskRunner()); 
t2.start();

Thread States: NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED

Synchronization primitives:

  • synchronized: Built-in lock mechanism
  • wait(), notify(), notifyAll(): Object-level communication (must be called within synchronized block)
  • Thread.sleep(): Pauses execution without releasing locks

Thread pools via ExecutorService manage thread lifecycle efficiently:

ExecutorService executor = Executors.newFixedThreadPool(4); 
executor.submit(() -> processTask()); 
executor.shutdown();

11. I/O Operations

Byte streams (InputStream/OutputStream) handle binary data. Character streams (Reader/Writer) handle text with proper encoding. BufferedReader and BufferedWriter provide efficient buffered operations.

try (BufferedReader reader = new BufferedReader(new FileReader("input.txt")); 
     BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) { 
    String line; 
    while ((line = reader.readLine()) != null) { 
        writer.write(line.toUpperCase()); 
        writer.newLine(); 
    } 
} // Automatic resource management with try-with-resources

12. Framework Integration

Spring Framework provides dependency injection and aspect-oriented programming. Core components include:

  • IoC Container: Manages bean lifecycle and dependencies
  • AOP: Cross-cutting concerns like logging and transactions
  • Spring MVC: DispatcherServlet as front controller

MyBatis maps Java methods to SQL statements through XML or annotation configuration, separating SQL from application code.

13. Common Pitfalls

  • Comparing objects with == instead of equals()
  • Modifying collections while iterating (use Iterator.remove())
  • Float/Double precision issues (use BigDecimal for financial calculations)
  • Missing break statements in switch causing fall-through
  • Forgetting that array length is an attribute, not a method

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.