Java Notes — From Scratch to OOP

Clear, detailed, beginner-friendly notes to learn Java step by step. Study each topic in depth and use the Table of Contents to jump.

Introduction: What is Java?

Java is a high-level, class-based, object-oriented programming language made to be platform-independent and easy to use. It focuses on readability, maintainability, and robustness. Java programs run on the Java Virtual Machine (JVM), which allows the same compiled code to run on many different operating systems.

Key properties: WORA (Write Once Run Anywhere), automatic memory management (garbage collection), strong type checking, and built-in concurrency support.

Who should learn Java? Beginners who want a modern language with strong OOP support, students preparing for software roles, or anyone building cross-platform backend systems or Android apps.

JVM, JRE, JDK — How Java runs

Understanding how Java code becomes a running program is essential.

Workflow:

Source (.java) --javac--> Bytecode (.class) --java/JVM--> Runs on platform

Simple ASCII diagram:

+-----------+   javac   +-----------+   java/JVM  +-----------+
| Hello.java| --------> | Hello.class| ---------> |   (OS)    |
+-----------+           +-----------+            +-----------+
      (source)            (bytecode)               (runs)

Getting Started: Install & Run

Windows/Mac/Linux (brief):

  1. Download and install the latest JDK from Oracle or OpenJDK distribution.
  2. Set JAVA_HOME environment variable to JDK path (optional but useful).
  3. Open terminal/command prompt. Check with javac -version and java -version.
  4. Create HelloWorld.java, write code, compile with javac HelloWorld.java, then run with java HelloWorld.

If you use an IDE (Eclipse, IntelliJ IDEA, VSCode with Java extensions), it automates compile/run but you should still know command-line steps.

Hello World & Compilation

Code:

Show HelloWorld.java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Notes:

Data Types (Detailed)

Java has two categories of types:

  1. Primitive types: fixed-size data types. They store values directly.
  2. Reference types: classes, arrays — variables store references (addresses) to objects.

Primitive types

Reference types

Objects created from classes (e.g., String, user-defined classes), arrays, and interfaces are reference types. A variable holds a reference (pointer) to a memory location in the heap.

Wrapper classes

Each primitive has an object wrapper: Integer, Long, Double, Character, Boolean. Useful when working with collections that require objects (e.g., ArrayList).

Example & notes

int a = 10;
long big = 10000000000L;
double d = 3.14;
char c = 'A';
boolean flag = true;
String s = "hello"; // String is a reference type

Important: primitives are not null; reference variables can be null.

Variables, Scope & Memory

Types of variables:

Example

public class Counter {
    private int count; // instance variable
    private static int totalCounters; // static variable

    public Counter() {
        count = 0;
        totalCounters++;
    }
}

Scope rules

Operators — explained

Arithmetic

+ - * / % — note integer division truncates decimal part.

int x = 7 / 2; // 3
double y = 7.0 / 2; // 3.5

Assignment

= += -= *= /= %=

Relational

== != > < >= <= — used for comparisons. For objects, == compares references, use equals() for value comparison (if overridden).

Logical

&& || ! — boolean logic; note short-circuit behavior of && and ||.

Bitwise & Shift

& | ^ ~ << >> >>> — useful for low-level operations and masks.

Example: equals vs ==

String a = new String("hi");
String b = new String("hi");
System.out.println(a == b); // false (different objects)
System.out.println(a.equals(b)); // true (same content)

Control Flow (if, switch, loops)

If / else

if (score >= 90) {
    grade = 'A';
} else if (score >= 75) {
    grade = 'B';
} else {
    grade = 'C';
}

Switch

Switch works with int, String (since Java 7), enums, and a few primitive wrappers.

switch (day) {
  case "Mon":
    // ...
    break;
  default:
    // ...
}

For loop

for (int i = 0; i < n; i++) {
    // repeated code
}

Enhanced for (for-each)

for (String name : names) {
    System.out.println(name);
}

While & Do-While

while (condition) {
    // runs while condition true
}

do {
   // runs at least once
} while (condition);

Loop control

break exits loop; continue skips to next iteration.

Methods & Parameter Passing

Methods are functions defined inside classes. They encapsulate behavior. Method declaration includes return type, name, parameters, and body.

Example

Show example methods
public class MathUtil {
    // method with two int parameters and int return
    public int add(int a, int b) {
        return a + b;
    }

    // overloaded method with double
    public double add(double a, double b) {
        return a + b;
    }
}

Pass-by-value

Java uses pass-by-value for method parameters. For primitives, value is copied. For objects, the reference is copied (so the method receives a copy of the reference pointing to the same object). This means you can modify the object's internal state but cannot change the caller's reference to point to a different object.

Example: modifying object inside method

void changeName(Person p) {
    p.setName("NewName"); // modifies original object
}

void reassign(Person p) {
    p = new Person("Another"); // only changes local copy of reference
}

Classes and Objects

Class is a blueprint that defines fields (data) and methods (behavior). An object is an instance of a class.

Example: simple class

Show Person class
public class Person {
    String name; // field
    int age;     // field

    public void sayHello() {
        System.out.println("Hello, my name is " + name);
    }
}

// creating objects:
Person p = new Person();
p.name = "Arun";
p.age = 20;
p.sayHello();

Memory layout (simple)

Objects are stored in the heap. Local references (variables) referring to objects are stored on the stack (inside methods).

Constructors & the this keyword

Constructor is a special method called when an object is created. It has the same name as the class and no return type.

Show constructor examples
public class Student {
    private String name;
    private int roll;

    // default constructor
    public Student() {
        this.name = "Unknown";
        this.roll = 0;
    }

    // parameterized constructor
    public Student(String name, int roll) {
        this.name = name; // 'this' used to refer instance variable
        this.roll = roll;
    }
}

Student s1 = new Student();
Student s2 = new Student("Meena", 12);

this refers to the current object. It's useful to disambiguate instance variables from parameters, or to call other constructors using this(...).

Encapsulation (getters & setters)

Encapsulation hides internal state and exposes behavior through methods. Use private for fields and provide public getters/setters.

Show encapsulation example
public class Account {
    private double balance;

    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) balance += amount;
    }
}

Benefits: control access, validate input, and maintain invariants.

Inheritance (extends)

Inheritance allows a class to reuse fields and methods from another class. class Sub extends Super.

Show inheritance example
public class Animal {
    public void eat() { System.out.println("eating"); }
}

public class Dog extends Animal {
    public void bark() { System.out.println("barking"); }
}

Dog d = new Dog();
d.eat(); // inherited
d.bark();

Java supports single inheritance for classes (a class can extend only one class) but allows multiple interfaces.

Polymorphism (Overloading & Overriding)

Method Overloading (compile-time)

Same method name, different parameter lists in the same class.

class Printer {
    void print(String s) { }
    void print(int n) { }
}

Method Overriding (runtime)

Subclass provides a specific implementation of a method declared in parent class. This enables dynamic method dispatch.

Show overriding example
class Animal {
    void sound() { System.out.println("some sound"); }
}
class Cat extends Animal {
    @Override
    void sound() { System.out.println("meow"); }
}

Animal a = new Cat();
a.sound(); // prints "meow" -> runtime decides

Polymorphism allows writing code that works on the base type while concrete classes provide behavior.

Abstraction & Interfaces

Abstraction focuses on what an object can do rather than how it does it. Use abstract classes or interface to declare methods without full implementation.

Show interface example
interface Flyable {
    void fly();
}

class Bird implements Flyable {
    public void fly() { System.out.println("Bird flying"); }
}

Since Java 8, interfaces can have default and static methods with implementations.

Practice Exercises

  1. Print Fibonacci series up to n terms.
  2. Check palindrome for string and number.
  3. Simple class project: Create Book class with fields and methods for borrowing/returning and maintain stock count (use static).
  4. Inheritance exercise: Create Vehicle, extend Car and Bike, override a start() method.

Try writing code on your own; then compare with answers (you can ask me for solutions anytime).

📚 References & Resources

Learn Java in your preferred language:

Tamil

English

Hindi

💻 Practice Platforms

After learning, strengthen your skills by practicing on coding platforms:

🤝 Connect with Me

If you want to connect, collaborate, or follow my journey, here’s my LinkedIn:

🌐 Shruthi M G on LinkedIn