Study material

Java fundamentals

Attachments(4)

Quiz
Quiz
Link
Java Documentation - Get Started
YouTube
Java in 100 Seconds
Drawing
Untitled Drawing

Java Primitive Data Types and Variable Modifiers

Java is a statically-typed language, meaning all variables must be declared with a specific data type before they can be used. These data types are broadly divided into primitive types (which store raw values) and reference types (which reference objects in memory).

The char Primitive Type

The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive). Unlike languages like C/C++ where characters are 8-bit ASCII, Java uses Unicode to support international character sets.

char grade = 'A';
char currency = '¥';

Common Misconception: Do not confuse char literals with String literals. A char literal must always be enclosed in single quotes ('A'), while a String literal must be enclosed in double quotes ("A"). A String is an object that handles a sequence of characters, not a primitive type.

Primitive Types Comparison

The table below details fundamental primitive types alongside char for context:

Data TypeSize (Bits)CategoryDefault ValueExample Literal
byte8Integer0(byte) 10
short16Integer0(short) 500
int32Integer0100000
long64Integer0L15000000000L
float32Floating-Point0.0f3.14f
double64Floating-Point0.0d2.71828
char16Character'\u0000''Z'
boolean1 (logical)Booleanfalsetrue

The final Modifier

The final keyword is a non-access modifier used to restrict the user from altering a variable, method, or class. When applied to a variable, it signifies that the value cannot be changed after initialization, effectively creating a constant.

  • Blank Final Variable: A final variable that is not initialized at the time of declaration. It must be initialized within the instance initializer block or the constructor before object creation completes.
  • Reference Variables: When a reference variable is marked final, the reference itself cannot change (it cannot point to a new object), but the internal state of the object it points to can still be modified.
final int MAX_VELOCITY = 120;
// MAX_VELOCITY = 150; // Compile-time error: cannot assign a value to final variable

final int[] DATA_POINTS = {1, 2, 3};
DATA_POINTS[0] = 10; // Allowed: modifying the content of the array
// DATA_POINTS = new int[]{4, 5, 6}; // Compile-time error: cannot reassign reference

Self-Check Questions

  1. What happens if a class tries to reassign a value to a final static variable inside a standard method?
  2. How many distinct values can a char data type represent in Java?

Summary: Java uses char as a 16-bit Unicode container for single characters, while the final keyword locks a variable's value or reference address post-initialization.


Object-Oriented Programming Principles

Java is an object-oriented programming (OOP) language built around objects containing data and behaviors.

Encapsulation

Encapsulation is the mechanism of bundling data (variables) and the code acting on them (methods) together as a single unit, while restricting direct access to some components. This is achieved by declaring class variables as private and providing access via public getters and setters.

public class BankAccount {
    private double balance; // Hidden internal state

    public double getBalance() { // Controlled exposure
        return this.balance;
    }

    public void deposit(double amount) {
        if (amount > 0) { // Validation logic
            this.balance += amount;
        }
    }
}

Inheritance and the extends Keyword

Inheritance is the process by which one class acquires the properties and behaviors of another. The extends keyword establishes an inheritance relationship, indicating that a subclass derives from a superclass. Java supports single inheritance for classes; a class can only extend one superclass.

public class Animal {
    public void eat() {
        System.out.println("Eating...");
    }
}

public class Dog extends Animal { // Dog inherits eat()
    public void bark() {
        System.out.println("Barking...");
    }
}

Polymorphism: Method Overloading

Polymorphism ("many forms") allows objects to be treated as instances of their parent class or interface. A compile-time variant of this is method overloading, which occurs when a single class contains multiple methods with the identical name but distinct parameter lists.

A parameter list is distinct if it differs by:

  1. The number of parameters.
  2. The types of parameters.
  3. The sequence of parameter types.
public class MathOperations {
    public int add(int a, int b) { return a + b; }
    public double add(double a, double b) { return a + b; } // Overloaded by type
    public int add(int a, int b, int c) { return a + b + c; } // Overloaded by count
}

Common Misconception: Changing only the return type or the access modifier of a method does not constitute method overloading. If two methods have the exact same name and parameter signatures but different return types, the compiler will throw an error.

Self-Check Questions

  1. Why does changing only the return type of a method fail to satisfy method overloading rules?
  2. How does encapsulation improve code maintenance and security?

Summary: Encapsulation secures data within classes using private accessors, inheritance utilizes extends to reuse class structures, and method overloading enables static polymorphism via unique parameter signatures.


Control Flow: Loops

Control flow statements break up the execution path of a program using decision-making, looping, and branching.

The do-while Loop

The do-while loop is a post-test loop. Unlike for and while loops, which test their condition at the top of the loop, the do-while loop evaluates its boolean expression at the bottom. This structural placement guarantees that the loop body executes at least once regardless of whether the conditional statement is true or false initially.

Code Comparison of Loops

// While loop: condition checked first. Body might execute 0 times.
int count = 10;
while (count < 5) {
    System.out.println("While loop executed"); // Never prints
    count++;
}

// Do-while loop: body executed first. Guaranteed to execute at least once.
int total = 10;
do {
    System.out.println("Do-while loop executed"); // Prints exactly once
    total++;
} while (total < 5);

Self-Check Questions

  1. Convert a standard for loop that runs 5 times into an equivalent do-while loop.
  2. What happens to a do-while loop if the termination condition never becomes false?

Summary: The do-while loop operates as a post-test loop structure, ensuring the body runs at least once before testing the condition.


Arrays and Methods

Array Declaration and Initialization

An array is a container object that holds a fixed number of values of a single type. The length of an array is established when the array is created and remains fixed.

// Preferred Java syntax: Declaration and inline initialization
int[] numbers = {1, 2, 3, 4, 5}; 

// Alternate valid declaration, followed by instantiation
int[] alternateNumbers = new int[5]; // Allocated memory for 5 ints, initialized to 0s

Common Misconception: Writing int numbers[] = {1, 2, 3}; is valid C/C++ style syntax which Java supports for compatibility. However, it is considered poor practice in Java. The brackets belong with the type declaration (int[]), not the variable name.

Method Declarations and the void Keyword

A method declaration defines the method's attributes, such as access level, return type, name, and arguments. The void keyword specifies that a method does not return any value when it executes.

public class DisplayUtility {
    // This method returns nothing; it performs an action (printing)
    public void printMessage(String message) {
        System.out.println("Message: " + message);
        // return; // Optional statement, no value allowed
    }
}

Self-Check Questions

  1. What index position corresponds to the final element in an array declared as int[] items = new int[10];?
  2. Can a method declared with a void return type contain a return keyword?

Summary: Arrays hold fixed-size ordered elements initialized inline via curly braces, while methods requiring no return payload use the void designation.


Advanced Java Structures: Interfaces and Exception Handling

Interfaces

An interface is a reference type in Java, similar to a class, that can contain only constants, method signatures, default methods, static methods, and nested types.

Historically (prior to Java 8), interfaces could only contain abstract methods and public static final constants. Any variable declared in an interface is implicitly public, static, and final.

public interface Vehicle {
    int MAX_SPEED = 120; // Implicitly public static final
    void accelerate();   // Implicitly public abstract
}

Classes conform to an interface specification using the implements keyword.

Exception Handling with try-catch

Java uses exceptions to handle errors and abnormal events during runtime. The try-catch block is the foundational structure used to handle these exceptions without crashing the program application.

  • try block: Encloses code that might throw an exception.
  • catch block: Encloses code to handle the exception if one matches the thrown exception type.
try {
    int[] myNumbers = {1, 2, 3};
    System.out.println(myNumbers[10]); // Throws ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
    System.err.println("Requested index does not exist: " + e.getMessage());
}

Self-Check Questions

  1. Can an interface be instantiated directly using the new keyword?
  2. What block can be appended after a try-catch structure to ensure code executes whether an exception occurs or not?

Summary: Interfaces establish behavioral contracts consisting of constants and abstract declarations, while try-catch pairings establish safeguards against unexpected execution errors.