Java Programming Notes
(Agile Software Development)
Java Features & JVM
01 ยท Features ยท Bytecode ยท JVM Architecture๐ Platform Independent
Java code is compiled into bytecode which runs on any JVM, regardless of the underlying OS โ "Write Once, Run Anywhere."
๐ Object-Oriented
Everything in Java revolves around classes and objects. Supports encapsulation, inheritance, polymorphism, and abstraction.
๐ก๏ธ Secure & Robust
- No explicit pointers
- Strong type checking
- Exception handling
- Automatic garbage collection
๐ Distributed & Multithreaded
Built-in support for network programming (TCP/IP) and concurrent programming with multiple threads of execution.
| Component | Role |
|---|---|
| Class Loader | Loads .class files into memory; performs loading, linking, and initialization |
| Method Area | Stores class metadata, static variables, method bytecode |
| Heap | Runtime data area where objects are allocated |
| Stack | Each thread has its own stack storing frames (local vars, operand stack) |
| Execution Engine | Executes bytecode using Interpreter + JIT Compiler |
| Garbage Collector | Automatically reclaims unused heap memory |
// Java Source Code (.java)
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
// Compilation: javac HelloWorld.java โ HelloWorld.class (Bytecode)
// Execution: java HelloWorld โ JVM interprets/compiles bytecode
Java
Class & Object Fundamentals
02 ยท Objects ยท References ยท Garbage Collection๐ Class
A blueprint/template that defines attributes (fields) and behaviors (methods). It is a logical entity โ no memory allocated at class declaration.
๐ท Object
An instance of a class. Memory is allocated on the heap when an object is created using the new keyword.
class Car {
// Fields (attributes)
String model;
int speed;
// Method (behavior)
void accelerate() {
speed += 10;
System.out.println("Speed: " + speed);
}
}
// Object creation
Car myCar = new Car(); // myCar is a reference variable
myCar.model = "Tesla";
myCar.accelerate();
Car anotherRef = myCar; // both point to same object!Java
โป๏ธ How GC Works
- JVM automatically reclaims heap memory
- Objects with no references are eligible
- Cannot force GC โ only System.gc() suggests it
- GC runs in a low-priority daemon thread
๐ GC Algorithms
- Mark & Sweep โ mark live, sweep dead
- Generational GC โ Young/Old/PermGen
- G1 GC โ default in Java 9+
- ZGC / Shenandoah โ low-latency
Car c = new Car(); // Object created on heap
c = null; // Object now eligible for GC
// Requesting GC (not guaranteed)
System.gc();
Runtime.getRuntime().gc();Java
Constructors & Initialization Code Blocks
03 ยท Constructors ยท Instance Initializers ยท Static BlocksA constructor is a special method called when an object is created. It has the same name as the class and no return type.
| Type | Description | Example |
|---|---|---|
| Default Constructor | No-arg, auto-provided if none defined | Car() |
| Parameterized Constructor | Accepts arguments to initialize fields | Car(String m, int s) |
| Copy Constructor | Creates new object from existing one | Car(Car c) |
class Student {
String name;
int age;
// Static initializer block โ runs once when class is loaded
static {
System.out.println("Class loaded!");
}
// Instance initializer block โ runs before every constructor
{
age = 18; // default age
}
// Default constructor
Student() { name = "Unknown"; }
// Parameterized constructor
Student(String n, int a) {
name = n;
age = a;
}
// Constructor chaining with this()
Student(String n) {
this(n, 18); // calls parameterized constructor
}
}Java
Access Control & Modifiers
04 ยท Access Specifiers ยท Non-Access Modifiers| Modifier | Same Class | Same Package | Subclass | Other Package |
|---|---|---|---|---|
| public | โ | โ | โ | โ |
| protected | โ | โ | โ | โ |
| default | โ | โ | โ | โ |
| private | โ | โ | โ | โ |
๐ final
- Variable: constant, can't reassign
- Method: can't be overridden
- Class: can't be extended (e.g., String)
๐ static
- Belongs to class, not instance
- Shared across all objects
- Called via class name
- Cannot access instance members directly
๐ abstract
- Class: cannot be instantiated
- Method: no body, must be overridden
- Requires at least one abstract method to declare class abstract
๐ synchronized / volatile
- synchronized: thread-safe method/block
- volatile: variable always read from main memory
- transient: skip during serialization
final class Constants {
public static final double PI = 3.14159; // constant
private transient int tempData; // not serialized
private volatile boolean flag = true; // thread-visible
}Java
Nested, Inner & Anonymous Classes
05 ยท Inner Class ยท Static Nested ยท Anonymous ยท Local| Type | Access to Outer | Use Case |
|---|---|---|
| Static Nested | Static members only | Grouping classes logically |
| Inner (Non-static) | All members incl. private | Accessing outer class state |
| Local Class | final/effectively final vars | Defined inside a method |
| Anonymous | final/effectively final vars | One-off interface implementation |
class Outer {
private int x = 10;
// Inner class
class Inner {
void show() { System.out.println(x); } // accesses outer x
}
// Static nested class
static class Nested {
void display() { System.out.println("Static nested"); }
}
void method() {
// Local class
class Local { void run() {} }
// Anonymous class implementing Runnable
Runnable r = new Runnable() {
public void run() { System.out.println("Running!"); }
};
r.run();
}
}
// Creating inner class instance (requires outer instance)
Outer o = new Outer();
Outer.Inner i = o.new Inner();
Outer.Nested n = new Outer.Nested(); // no outer instance neededJava
Abstract Classes & Interfaces
06 ยท Abstract ยท Interface ยท Default Methods ยท Functional Interface๐ท Abstract Class
- Can have abstract + concrete methods
- Can have constructors & fields
- Single inheritance only
- Use when classes share implementation
๐ถ Interface
- All methods implicitly public abstract
- Fields are public static final
- Multiple implementation (Java 8+: default/static methods)
- Use for defining contracts/capabilities
// Abstract class
abstract class Shape {
String color;
Shape(String c) { color = c; }
abstract double area(); // must override
void describe() { // concrete method
System.out.println("Color: " + color);
}
}
// Interface with default method (Java 8+)
interface Drawable {
void draw(); // abstract
default void render() { // default (Java 8+)
System.out.println("Rendering...");
}
static void info() { // static method
System.out.println("Drawable interface");
}
}
class Circle extends Shape implements Drawable {
double radius;
Circle(String c, double r) { super(c); radius = r; }
public double area() { return Math.PI * radius * radius; }
public void draw() { System.out.println("Drawing circle"); }
}Java
Defining Methods & Method Overloading
07 ยท Method Syntax ยท Overloading ยท varargs// modifier returnType methodName(params) throws Exception
public static int add(int a, int b) {
return a + b;
}
// Varargs - variable number of arguments
public int sum(int... nums) {
int total = 0;
for (int n : nums) total += n;
return total;
}Java
class Calculator {
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
int add(int a, int b, int c) { return a + b + c; }
String add(String a, String b) { return a + b; }
}
// Each call is resolved by the compiler based on argument typesJava
Recursion
08 ยท Base Case ยท Recursive Case ยท Call StackRecursion occurs when a method calls itself. Every recursive solution needs a base case (stops recursion) and a recursive case (moves toward base case).
// Factorial: n! = n ร (n-1)!
int factorial(int n) {
if (n <= 1) return 1; // Base case
return n * factorial(n - 1); // Recursive case
}
// Fibonacci: fib(n) = fib(n-1) + fib(n-2)
int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
}
// Stack trace for factorial(3):
// factorial(3) โ 3 ร factorial(2)
// factorial(2) โ 2 ร factorial(1)
// factorial(1) โ 1 (base case)
// returns 2 ร 1 = 2
// returns 3 ร 2 = 6Java
Dealing with Static Members
09 ยท Static Variables ยท Static Methods ยท Static Blocks๐ Static Variables
- Belong to class, not objects
- Shared across all instances
- One copy in memory (Method Area)
- Used for: counters, constants
โ๏ธ Static Methods
- Called on class, not instance
- Cannot use this keyword
- Cannot access non-static members directly
- Used for: utility/factory methods
class BankAccount {
private static int totalAccounts = 0; // class-level counter
private int balance;
static {
System.out.println("BankAccount class loaded");
}
BankAccount() { totalAccounts++; }
public static int getTotalAccounts() {
return totalAccounts; // OK: accessing static from static
// return balance; // ERROR: cannot access instance var
}
}
// Calling static method
System.out.println(BankAccount.getTotalAccounts());Java
finalize(), Native Methods & 'this' Reference
10 ยท finalize ยท native ยท this keyword ยท Use of ModifiersCalled by the GC before reclaiming an object's memory. Used for cleanup (closing resources). Deprecated since Java 9 โ prefer try-with-resources or Cleaner.
class Resource {
protected void finalize() throws Throwable {
try {
System.out.println("Cleaning up resource...");
// close file handles, DB connections, etc.
} finally {
super.finalize(); // always call super
}
}
}Java
class NativeDemo {
public native void nativeMethod(); // no body!
static {
System.loadLibrary("nativeLib"); // load .dll/.so file
}
}Java
๐ต Uses of this
- Refer to current object's fields/methods
- Disambiguate when param names clash with fields
- Call another constructor: this(args)
- Pass current object as argument
- Return current object from method
๐ต this in Builder Pattern
class Builder {
String name;
Builder setName(String n) {
this.name = n;
return this; // method chaining
}
}
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name; // this.name = field, name = param
this.age = age;
}
Person(String name) {
this(name, 0); // constructor chaining โ must be first statement
}
void greet(Greeter g) {
g.greetPerson(this); // passing current object
}
}Java
Design of Accessor & Mutator Methods
11 ยท Getters ยท Setters ยท Encapsulation ยท Design Principles๐ Accessor (Getter)
Returns the value of a private field. Named getFieldName() or isFieldName() for booleans. Makes fields readable without direct access.
โ๏ธ Mutator (Setter)
Sets/modifies a private field value. Named setFieldName(value). Enables validation logic before changing state.
class Employee {
private String name;
private double salary;
private boolean active;
// Accessor (getter)
public String getName() { return name; }
public double getSalary() { return salary; }
public boolean isActive() { return active; } // boolean: 'is'
// Mutator (setter) with validation
public void setName(String name) {
if (name == null || name.isBlank())
throw new IllegalArgumentException("Name cannot be empty");
this.name = name;
}
public void setSalary(double salary) {
if (salary < 0)
throw new IllegalArgumentException("Salary cannot be negative");
this.salary = salary;
}
}
// Usage: JavaBeans convention
Employee e = new Employee();
e.setName("Alice");
System.out.println(e.getName());Java
Cloning Objects, Shallow/Deep Copy & Generics
12 ยท clone() ยท Shallow Copy ยท Deep Copy ยท Generic Types๐ช Shallow Copy
Copies field values directly. Primitive fields are copied by value. Reference fields point to the same object โ not duplicated.
Default Object.clone() performs shallow copy.
๐ Deep Copy
Recursively copies all objects referenced. Creates completely independent copies of all nested objects. Must be manually implemented or via serialization.
// Shallow Copy
class Address {
String city;
Address(String c) { city = c; }
}
class Person implements Cloneable {
String name;
Address address; // reference type
// SHALLOW CLONE โ address is NOT duplicated
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// DEEP CLONE โ address IS duplicated
Person deepClone() {
Person copy = new Person();
copy.name = this.name;
copy.address = new Address(this.address.city); // new object!
return copy;
}
}
Person p1 = new Person(); p1.name = "Alice"; p1.address = new Address("NY");
Person p2 = p1.deepClone();
p2.address.city = "LA"; // p1.address.city still "NY"Java
Generics enable writing type-safe code that works with any data type, catching type errors at compile time rather than runtime.
// Generic class
class Box<T> {
private T item;
public void set(T item) { this.item = item; }
public T get() { return item; }
}
// Generic method
public static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// Wildcards
void printList(List<?> list) { ... } // unknown type
void addNums(List<? super Integer> l) { ... } // lower bound
void readNums(List<? extends Number> l) { ... } // upper bound
// Usage
Box<String> strBox = new Box<>();
strBox.set("Hello");
String s = strBox.get(); // no cast needed!Java
Array and String
13 ยท Arrays ยท Multi-dim ยท String Ops ยท StringBuffer ยท StringBuilder๐ฆ Array Declaration
- Fixed-size, homogeneous data structure
- Zero-indexed, stored in contiguous memory
- Default values: 0, false, null
- array.length gives size (not a method)
๐ข Multi-Dimensional Arrays
- 2D: int[][] mat = new int[3][4]
- Jagged arrays: rows of different lengths
- Accessed via mat[row][col]
- Enhanced for-loop for iteration
// Array declaration and initialization
int[] nums = new int[5]; // default zeros
int[] primes = {2, 3, 5, 7, 11}; // array literal
String[] names = new String[]{"Alice", "Bob"};
// Accessing
System.out.println(primes[0]); // 2
System.out.println(primes.length); // 5
// Enhanced for-loop
for (int p : primes) System.out.print(p + " ");
// 2D Array (Matrix)
int[][] matrix = {{1,2},{3,4},{5,6}};
for (int[] row : matrix)
for (int val : row) System.out.print(val + "\t");
// Jagged array
int[][] jagged = new int[3][];
jagged[0] = new int[2]; jagged[1] = new int[4]; jagged[2] = new int[1];Java
| Method | Description | Example |
|---|---|---|
| length() | Returns character count | "hello".length() โ 5 |
| charAt(i) | Char at index i | "abc".charAt(1) โ 'b' |
| substring(s,e) | Extracts substring | "hello".substring(1,3) โ "el" |
| indexOf(s) | First occurrence index | "hello".indexOf('l') โ 2 |
| toUpperCase() | Convert to uppercase | "hi".toUpperCase() โ "HI" |
| trim() | Strip leading/trailing spaces | " hi ".trim() โ "hi" |
| replace(a,b) | Replace characters/substrings | "cat".replace('c','b') โ "bat" |
| split(regex) | Split into String array | "a,b,c".split(",") โ ["a","b","c"] |
| equals(s) | Content equality (use over ==) | "abc".equals("abc") โ true |
| compareTo(s) | Lexicographic comparison | Returns 0 if equal |
๐ String (Immutable)
- Cannot be modified after creation
- Every change creates a new object
- Thread-safe, can be shared
- Cached in String Pool
๐ StringBuilder / StringBuffer (Mutable)
- StringBuilder: fast, not thread-safe
- StringBuffer: synchronized, thread-safe
- Modify in-place (same object)
- Use for heavy string concatenation
// Immutable String โ creates new objects
String s = "Hello";
s = s + " World"; // old "Hello" object abandoned
// StringBuilder โ modifies in-place
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // same object
sb.insert(5, ","); // "Hello, World"
sb.delete(0, 5); // ", World"
sb.reverse(); // "dlroW ,"
sb.replace(0, 2, "XX"); // replace range
String result = sb.toString();
// StringBuffer (thread-safe, same API as StringBuilder)
StringBuffer buf = new StringBuffer();
buf.append("safe"); // synchronized
// Tokenizing with StringTokenizer
import java.util.StringTokenizer;
StringTokenizer st = new StringTokenizer("one two three", " ");
while (st.hasMoreTokens())
System.out.println(st.nextToken());
// Loop over characters
for (int i = 0; i < s.length(); i++)
System.out.print(s.charAt(i));
// Collection classes for strings
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));Java
Inheritance
14 ยท Types ยท Constructors ยท Overriding ยท super ยท Polymorphismโ Why Inherit?
- Code reuse โ avoid duplication
- Extensibility โ add new behavior
- Polymorphism โ unified interface
- Maintainability โ change in one place
๐ Types of Inheritance
- Single โ A extends B
- Multilevel โ A โ B โ C
- Hierarchical โ B, C both extend A
- Multiple โ via interfaces only in Java
class Animal {
String name;
Animal(String name) { this.name = name; }
void speak() { System.out.println("..."); }
void breathe() { System.out.println("Breathing"); }
}
class Dog extends Animal {
String breed;
// Constructor chaining with super()
Dog(String name, String breed) {
super(name); // must be first!
this.breed = breed;
}
// Method overriding
@Override
void speak() {
super.speak(); // call parent version
System.out.println("Woof!");
}
}
class GoldenRetriever extends Dog { // Multilevel
GoldenRetriever(String name) { super(name, "Golden"); }
}Java
| Rule | Detail |
|---|---|
| Same signature | Same name, same parameter list |
| Return type | Same or covariant (subtype) return type |
| Access modifier | Cannot be more restrictive than parent |
| Cannot override | static, final, private methods |
| @Override | Annotation recommended โ compile-time check |
// Runtime Polymorphism (dynamic dispatch)
Animal a = new Dog("Rex", "Labrador"); // upcasting (implicit)
a.speak(); // calls Dog's speak() at runtime
// Downcasting (explicit, may throw ClassCastException)
if (a instanceof Dog) {
Dog d = (Dog) a; // safe downcast
System.out.println(d.breed);
}
// Implementing an interface
interface Swimmable { void swim(); }
class Duck extends Animal implements Swimmable {
Duck(String n) { super(n); }
public void swim() { System.out.println("Splashing!"); }
public void speak() { System.out.println("Quack!"); }
}Java
Packages
15 ยท Concept ยท Organizing Classes ยท Access Protection ยท ImportA package is a namespace that organizes related classes and interfaces into groups โ similar to folders in a file system. Packages prevent naming conflicts and control access.
๐ Built-in Packages
- java.lang โ auto-imported (String, Math, Object)
- java.util โ Collections, Scanner, Date
- java.io โ File I/O streams
- java.net โ Networking
- java.awt / javax.swing โ GUI
๐ Package as Access Protection
- default (no modifier): accessible within same package only
- public: accessible from any package
- protected: package + subclasses in other packages
- Package encapsulates implementation details
// File: com/myapp/utils/MathHelper.java
package com.myapp.utils; // must be first statement
public class MathHelper {
public static int square(int n) { return n * n; }
static void helper() {} // package-private (default)
}
// File: com/myapp/Main.java
package com.myapp;
import com.myapp.utils.MathHelper; // specific class
import com.myapp.utils.*; // all public classes
import static java.lang.Math.PI; // static import
public class Main {
public static void main(String[] args) {
System.out.println(MathHelper.square(5)); // 25
System.out.println(PI); // static import usage
}
}
// Directory structure mirrors package name:
// src/
// com/
// myapp/
// Main.java
// utils/
// MathHelper.javaJava
Exception Handling
16 ยท try-catch-finally ยท throw ยท throws ยท Checked vs UncheckedAn exception is an abnormal condition that disrupts normal program flow. Java separates error-handling code from regular code using a structured mechanism, making programs more robust and readable.
โ ๏ธ Errors vs Exceptions
- Error: JVM-level, unrecoverable (OutOfMemoryError, StackOverflowError)
- Exception: Application-level, recoverable
- Both extend Throwable
๐๏ธ Types of Exceptions
- Checked: must be handled or declared (IOException, SQLException)
- Unchecked: RuntimeExceptions (NullPointerException, ArrayIndexOutOfBoundsException)
| Class | Category | Example |
|---|---|---|
| Throwable | Root | All exceptions/errors |
| Error | JVM / System | OutOfMemoryError, StackOverflowError |
| Exception | Application | All checked exceptions |
| RuntimeException | Unchecked | NullPointerException, ClassCastException |
| IOException | Checked | FileNotFoundException |
// Basic try-catch-finally
try {
int[] arr = new int[3];
arr[5] = 10; // throws ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Index error: " + e.getMessage());
} catch (Exception e) { // catch-all (more specific first!)
e.printStackTrace();
} finally {
System.out.println("Always runs โ close resources here");
}
// Multi-catch (Java 7+)
try { ... }
catch (IOException | SQLException e) { e.printStackTrace(); }
// throw โ manually throw an exception
void setAge(int age) {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
this.age = age;
}
// throws โ declare checked exceptions in method signature
void readFile(String path) throws IOException {
new FileReader(path); // checked exception
}
// try-with-resources (Java 7+) โ auto-closes resources
try (FileReader fr = new FileReader("file.txt")) {
// fr.close() is called automatically
}
// User-defined exception
class InsufficientFundsException extends Exception {
double amount;
InsufficientFundsException(double amt) {
super("Insufficient funds: " + amt);
amount = amt;
}
}Java
Multithreading
17 ยท Thread Lifecycle ยท Priorities ยท Synchronization ยท DeadlockA thread is the smallest unit of execution within a process. Java supports multithreading natively, enabling concurrent tasks to run within a single program.
๐งต Thread Lifecycle
- NEW โ created, not started
- RUNNABLE โ running or ready
- BLOCKED โ waiting for monitor lock
- WAITING โ waiting indefinitely
- TIMED_WAITING โ waiting with timeout
- TERMINATED โ execution complete
๐ Thread Priorities
- Range: 1 (MIN) to 10 (MAX), default 5 (NORM)
- Set with t.setPriority(n)
- Higher priority โ guaranteed first execution
- JVM / OS schedules threads โ priority is a hint
// Method 1: Extending Thread class
class MyThread extends Thread {
public void run() { System.out.println("Thread running: " + getName()); }
}
// Method 2: Implementing Runnable (preferred)
class Task implements Runnable {
public void run() { System.out.println("Task running"); }
}
// Creating and starting threads
Thread t1 = new MyThread();
Thread t2 = new Thread(new Task());
Thread t3 = new Thread(() -> System.out.println("Lambda thread"));
t1.setPriority(Thread.MAX_PRIORITY); // priority 10
t1.start(); t2.start(); t3.start();
t1.join(); // wait for t1 to complete before continuing
Thread.sleep(1000); // pause current thread 1 secondJava
class Counter {
private int count = 0;
// Synchronized method โ only one thread at a time
public synchronized void increment() { count++; }
// Synchronized block โ finer control
public void add(int n) {
synchronized (this) { count += n; }
}
public int getCount() { return count; }
}
// Inter-thread communication (Producer-Consumer pattern)
class SharedBuffer {
private int data; private boolean ready = false;
public synchronized void produce(int v) throws InterruptedException {
while (ready) wait(); // release lock, wait
data = v; ready = true;
notifyAll(); // wake waiting threads
}
public synchronized int consume() throws InterruptedException {
while (!ready) wait();
ready = false;
notifyAll();
return data;
}
}Java
// Deadlock scenario
Object lockA = new Object(), lockB = new Object();
Thread t1 = new Thread(() -> {
synchronized (lockA) {
synchronized (lockB) { System.out.println("T1 done"); }
}
});
Thread t2 = new Thread(() -> {
synchronized (lockB) { // DEADLOCK: opposite lock order!
synchronized (lockA) { System.out.println("T2 done"); }
}
});
// Fix: both threads acquire lockA THEN lockBJava
Input / Output (I/O)
18 ยท Streams ยท File I/O ยท Buffers ยท Channels ยท SerializationA stream is a sequence of data flowing from a source to a destination. Java I/O is built around two stream hierarchies:
๐ต Byte Streams
- Handle raw binary data (8-bit bytes)
- InputStream / OutputStream (abstract roots)
- Subclasses: FileInputStream, BufferedInputStream, DataInputStream
- Used for images, audio, binary files
๐ข Character Streams
- Handle Unicode text (16-bit chars)
- Reader / Writer (abstract roots)
- Subclasses: FileReader, BufferedReader, PrintWriter
- Used for text files, console
| Stream | Object | Default Source/Dest |
|---|---|---|
| Standard Input | System.in | Keyboard |
| Standard Output | System.out | Console (stdout) |
| Standard Error | System.err | Console (stderr) |
import java.io.*;
import java.nio.file.*;
import java.nio.channels.*;
// Working with File object
File f = new File("data.txt");
System.out.println(f.exists()); // true/false
System.out.println(f.length()); // bytes
System.out.println(f.getName()); // "data.txt"
f.createNewFile(); // create if not exists
f.delete(); // delete file
// Writing to a file (BufferedWriter)
try (BufferedWriter bw = new BufferedWriter(new FileWriter("out.txt"))) {
bw.write("Hello, File!");
bw.newLine();
bw.write("Second line");
}
// Reading from a file (BufferedReader)
try (BufferedReader br = new BufferedReader(new FileReader("out.txt"))) {
String line;
while ((line = br.readLine()) != null)
System.out.println(line);
}
// PrintWriter for formatted output
try (PrintWriter pw = new PrintWriter(new FileWriter("log.txt", true))) {
pw.printf("Value: %d%n", 42); // append mode
}Java
// NIO FileChannel Read/Write with Buffer
try (FileChannel fc = FileChannel.open(Paths.get("data.bin"),
StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
// Write
ByteBuffer wBuf = ByteBuffer.allocate(64);
wBuf.put("NIO Channel Write".getBytes());
wBuf.flip(); // switch to read mode
fc.write(wBuf);
// Read
fc.position(0); // rewind
ByteBuffer rBuf = ByteBuffer.allocate(64);
fc.read(rBuf);
rBuf.flip();
System.out.println(new String(rBuf.array(), 0, rBuf.limit()));
}Java
import java.io.*;
class Student implements Serializable {
private static final long serialVersionUID = 1L;
String name;
int roll;
transient String password; // NOT serialized
}
// Serialize (write object to file)
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("student.ser"))) {
Student s = new Student(); s.name = "Alice"; s.roll = 101;
oos.writeObject(s);
}
// Deserialize (read object from file)
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("student.ser"))) {
Student s = (Student) ois.readObject();
System.out.println(s.name + " " + s.roll);
System.out.println(s.password); // null โ was transient
}Java