Skip to content

Java Quick Guide

Java is a high-level, class-based, object-oriented programming language designed to have as few implementation dependencies as possible. Key characteristics include:

  • Object-Oriented: Organizes software design around data, or objects, rather than functions and logic.
  • Platform Independent: Write Once, Run Anywhere (WORA) thanks to the Java Virtual Machine (JVM).
  • Simple: Designed to be relatively easy to learn, especially compared to C++.
  • Secure: Features like the Security Manager allow for safe execution of untrusted code.
  • Architecture-Neutral: Compiled code (bytecode) runs on any processor with a compatible JVM.
  • Portable: Same code runs on different platforms without modification.
  • Robust: Strong memory management and exception handling reduce common programming errors.
  • Multi-threaded: Supports concurrent execution of multiple parts of a program.
  • Interpreted & High Performance: Bytecode is interpreted by the JVM, which uses Just-In-Time (JIT) compilation for high performance.
  • Distributed: Facilitates developing distributed applications.
  • Dynamic: Designed to adapt to an evolving environment.

To develop Java applications, you need a Java Development Kit (JDK). You can download a JDK from various providers. Popular choices include Oracle JDK and OpenJDK distributions like Eclipse Temurin, Amazon Corretto, or Azul Zulu. It’s recommended to use a Long-Term Support (LTS) version (e.g., Java 11, 17, 21) for stability.

Installation guides are available on the respective JDK provider websites. Modern development typically involves:

  • Installing a JDK and setting the JAVA_HOME environment variable.
  • Using an Integrated Development Environment (IDE) like IntelliJ IDEA, Eclipse, or Visual Studio Code with Java extensions for coding, debugging, and running applications.
  • Employing a build automation tool like Maven or Gradle to manage project dependencies, compilation, testing, and packaging.

Refer to the documentation of your chosen JDK, IDE, and build tool for detailed setup instructions.

  • Object: An instance of a class, possessing state (data) and behavior (methods). Example: A specific Dog object might have states like color="Brown", name="Buddy", breed="Labrador" and behaviors like bark(), wagTail(), eat().
  • Class: A blueprint or template used to create objects. It defines the properties (fields/variables) and actions (methods) that all objects of that type will have.
  • Method: A block of code within a class that performs a specific task. Methods define an object’s behavior and contain the logic for manipulating data.
  • Instance Variables: Variables declared within a class but outside any method. Each object (instance) of the class has its own copy of these variables, defining its unique state.

Let’s look at a simple program that prints “Hello, Modern World!” to the console:

public class MyFirstJavaProgram {
/*
* This is a classic first Java program.
* It demonstrates the basic structure and prints a message to the console.
*/
// The main method is the entry point for any Java application.
public static void main(String[] args) {
// System.out.println is used to print output to the standard output stream (usually the console).
System.out.println("Hello, Modern World!");
}
}

Key points to remember about Java programs:

  • Case Sensitivity: Java is case-sensitive. myVariable and myvariable are treated as different identifiers.
  • Class Names: By convention, class names start with an uppercase letter and use UpperCamelCase (e.g., MyFirstJavaProgram).
  • Method Names: By convention, method names start with a lowercase letter and use lowerCamelCase (e.g., myMethodName()).
  • File Name: The source file name must exactly match the public class name within the file, appended with .java (e.g., MyFirstJavaProgram.java).
  • Main Method: Program execution begins in the public static void main(String[] args) method. This signature is essential. String... args (varargs) is also valid.

Identifiers are names given to classes, methods, variables, packages, etc. Rules for identifiers:

  • Must start with a letter (a-z, A-Z), currency character ($), or underscore (_).
  • Subsequent characters can be letters, digits (0-9), currency characters, or underscores.
  • Cannot be a Java keyword (reserved word like class, int, public).
  • Are case-sensitive.
  • Examples of valid identifiers: age, $salary, _value, __1_value, userName.
  • Examples of invalid identifiers: 123abc (starts with digit), -salary (starts with hyphen), class (keyword).

Modifiers alter the meaning or accessibility of classes, methods, variables, etc. They fall into two main categories:

  • Access Modifiers: Control visibility. public (accessible everywhere), protected (accessible within the package and subclasses), default (package-private, accessible only within the same package), private (accessible only within the declaring class).
  • Non-Access Modifiers: Provide other characteristics. Key examples include static (belongs to the class, not instances), final (cannot be changed/subclassed/overridden), abstract (must be implemented by a subclass), synchronized (controls thread access), volatile (ensures visibility of changes across threads), transient (excluded from serialization). strictfp ensures platform-independent floating-point results (less commonly used now).

Understanding modifiers is crucial for proper object-oriented design and concurrency control.

Variables are containers for storing data values. Java has three main types based on scope:

  • Local Variables: Declared inside a method, constructor, or block. Their scope is limited to that block.
  • Instance Variables (Non-Static Fields): Declared within a class but outside any method. Each object instance has its own copy.
  • Class Variables (Static Fields): Declared with the static keyword within a class, outside any method. There is only one copy shared among all instances of the class.

Since Java 10, you can use var for type inference of local variables, where the compiler deduces the type from the initializer: var message = "Hello";

Arrays are fixed-size, indexed collections storing multiple elements of the same data type. They are objects residing on the heap.

Example Declaration and Initialization:

// Declare an array of integers
int[] numbers;
// Allocate memory for 5 integers
numbers = new int[5];
// Initialize elements
numbers[0] = 10;
numbers[1] = 20;
// ... and so on
// Shorthand declaration and initialization
String[] names = {"Alice", "Bob", "Charlie"};

While arrays are fundamental, for dynamic collections (where size can change), the Java Collections Framework (e.g., ArrayList, LinkedList, HashMap) is often more flexible and preferred.

Enums define a type with a fixed set of named constants. They improve type safety and code clarity compared to using plain constants (e.g., integers or strings).

Example: Representing fixed sizes.

enum Size {
SMALL, MEDIUM, LARGE
}
public class CoffeeOrder {
private Size cupSize;
public void setSize(Size size) {
this.cupSize = size;
}
public Size getSize() {
return cupSize;
}
public static void main(String[] args) {
CoffeeOrder order = new CoffeeOrder();
order.setSize(Size.MEDIUM);
System.out.println("Ordered cup size: " + order.getSize()); // Output: Ordered cup size: MEDIUM
}
}

Enums in Java are powerful: they can have fields, methods, and constructors, and can implement interfaces. They are essentially special kinds of classes.

Keywords are reserved words with predefined meanings in the Java language. They cannot be used as identifiers. Here’s a list of common keywords (note: const and goto are reserved but not used):

abstractassertbooleanbreak
bytecasecatchchar
classcontinuedefault
dodoubleelseenum
extendsfinalfinallyfloat
forifimplements
importinstanceofintinterface
longnativenewpackage
privateprotectedpublicreturn
shortstaticstrictfpsuper
switchsynchronizedthisthrow
throwstransienttryvoid
volatilewhilevarrecord
sealedpermitsnon-sealedyield

Comments are ignored by the compiler and used to explain code. Java supports three types:

public class CommentDemo {
// This is a single-line comment. It ends at the end of the line.
/*
* This is a multi-line comment.
* It can span several lines.
*/
/**
* This is a Javadoc comment. It's used to generate API documentation.
* It typically precedes class, method, or field declarations.
* @param args Command-line arguments (not used here).
*/
public static void main(String[] args) {
System.out.println("Demonstrating comments."); // Comment after code
}
}

Java has two categories of data types:

  • Primitive Data Types: Fundamental types built into the language. They store simple values directly.
  • Reference/Object Data Types: Refer to objects (instances of classes). They store memory addresses where the object’s data resides.

Java supports eight primitive data types:

  • byte: 8-bit integer.
  • short: 16-bit integer.
  • int: 32-bit integer (most commonly used for whole numbers).
  • long: 64-bit integer (use when int is not large enough). Suffix L or l (e.g., 100L).
  • float: 32-bit single-precision floating-point. Suffix F or f (e.g., 3.14f).
  • double: 64-bit double-precision floating-point (default for decimal numbers). Suffix D or d optional.
  • boolean: Represents true or false values.
  • char: 16-bit Unicode character (enclosed in single quotes, e.g., 'A').
  • Reference variables are created using class constructors (e.g., String name = new String("Java"); or simply String name = "Java"; for Strings).
  • They hold references (memory addresses) to objects.
  • Examples include String, arrays, instances of custom classes (Dog, CoffeeOrder), interfaces, and enums.
  • The default value for any reference variable is null, meaning it doesn’t refer to any object.
  • A reference variable can refer to an object of its declared type or any compatible subtype (polymorphism).

A literal is a fixed value represented directly in the source code.

Examples of various literals:

int count = 100; // Integer literal
long bigNumber = 9876543210L; // Long literal (note the L)
double price = 29.99; // Double literal
float pi = 3.14f; // Float literal (note the f)
boolean isValid = true; // Boolean literal
char grade = 'A'; // Character literal
String message = "Hello"; // String literal
// Text Block (Java 15+) for multi-line strings
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>""";

String and char literals support special escape sequences for representing characters like newline (\n), tab (\t), backslash (\\), single quote (\'), and double quote (\").

NotationCharacter Represented
\nNewline
\rCarriage return
\fFormfeed
\bBackspace
\tTab
”Double quote
’Single quote
\Backslash

Access modifiers control the accessibility of classes, constructors, fields, and methods:

  • public: Accessible from any other class.
  • protected: Accessible within its own package and by subclasses (even if in different packages).
  • default (no keyword): Package-private. Accessible only by classes within the same package.
  • private: Accessible only within the declaring class itself.

Choosing the right access level is key to encapsulation, a core OOP principle.

Operators perform operations on variables and values. Common groups include:

Perform mathematical calculations. Example: int a = 10, b = 3;

OperatorDescriptionExampleResult
+Additiona + b13
-Subtractiona - b7
*Multiplicationa * b30
/Division (integer division for ints)a / b3
%Modulus (remainder)a % b1
++Increment (pre/post)a++ (value is 10, then a becomes 11)Varies
—Decrement (pre/post)—b (value is 2, b becomes 2)Varies

Compare two values, resulting in a boolean (true or false). Example: int x = 5, y = 8;

OperatorDescriptionExampleResult
==Equal tox == yfalse
!=Not equal tox != ytrue
>Greater thanx > yfalse
<Less thanx < ytrue
>=Greater than or equal tox >= 5true
<=Less than or equal toy <= 8true

Operate on the individual bits of integer types. Less common in general application code but used in specific scenarios (e.g., low-level programming, flag manipulation). Example: int a = 5; // 0101, int b = 3; // 0011

OperatorDescriptionExampleResult (Binary)
&Bitwise ANDa & b1 (0001)
|Bitwise ORa | b7 (0111)
^Bitwise XORa ^ b6 (0110)
~Bitwise Complement~a-6 (Inverts all bits)
<<Left Shifta << 110 (1010)
>>Signed Right Shifta >> 12 (0010)
>>>Unsigned Right Shifta >>> 12 (0010, same for positive numbers)

Combine boolean expressions. Example: boolean p = true, q = false;

OperatorDescriptionExampleResult
&&Logical AND (short-circuiting)p && qfalse
||Logical OR (short-circuiting)p || qtrue
!Logical NOT!pfalse

Assign values to variables. The compound operators perform an operation and assign in one step.

OperatorDescriptionExample
=Simple Assignmentint c = 10;
+=Add and Assignc += 5; (c = c + 5)
-=Subtract and Assignc -= 3; (c = c - 3)
*=Multiply and Assignc *= 2; (c = c * 2)
/=Divide and Assignc /= 4; (c = c / 4)
%=Modulus and Assignc %= 3; (c = c % 3)

A shorthand for if-else statements. Syntax: condition ? value_if_true : value_if_false.

int score = 75;
String result = (score >= 60) ? "Pass" : "Fail"; // result will be "Pass"

Checks if an object is an instance of a particular class, subclass, or implementation of an interface. Returns true or false.

String name = "Java";
boolean isString = name instanceof String; // isString will be true
// Modern Java (16+) includes Pattern Matching for instanceof:
Object obj = "Hello";
if (obj instanceof String s) {
// If obj is a String, assign it to s
System.out.println("String length: " + s.length());
} else {
System.out.println("Not a String");
}

Determines the order in which operators are evaluated in an expression. Parentheses () can override precedence. Higher precedence operators are evaluated first. Consult Java documentation for the full precedence table.

Example high-level precedence (highest to lowest): Postfix (expr++, expr--), Unary (++expr, !, ~), Multiplicative (*, /, %), Additive (+, -), Shift (<<, >>, >>>), Relational (<, >, <=, >=), Equality (==, !=), Bitwise AND (&), Bitwise XOR (^), Bitwise OR (|), Logical AND (&&), Logical OR (||), Ternary (? :), Assignment (=, +=, etc.).

Loops execute a block of code repeatedly.

Repeats a block as long as a boolean condition is true. The condition is checked before each iteration.

Syntax:

while (condition) {
// Statements to execute
}

Similar to while, but the condition is checked after the block executes. Guarantees the block runs at least once.

Syntax:

do {
// Statements to execute
} while (condition);

Ideal when the number of iterations is known. Consists of initialization, condition, and update expressions.

Syntax:

for (initialization; condition; update) {
// Statements to execute
}

Example: Print numbers 0 through 4

for (int i = 0; i < 5; i++) {
System.out.println(i);
}

Provides a simpler syntax for iterating over elements in arrays or collections.

Syntax:

for (ElementType variable : arrayOrCollection) {
// Statements using variable
}

Example: Print names from an array

String[] names = {"Alice", "Bob", "Charlie"};
for (String name : names) {
System.out.println(name);
}

Modify the flow of execution within loops.

Immediately terminates the innermost loop (for, while, do-while) or switch statement it is in. Execution continues at the statement following the terminated loop/switch.

Skips the current iteration of the innermost loop and proceeds to the next iteration. In a for loop, it jumps to the update expression; in while or do-while, it jumps to the condition check.

Syntax (used inside a loop):

break;
continue;

Execute different blocks of code based on conditions.

Executes a block of code only if a boolean condition is true.

Syntax:

if (condition) {
// Statements execute if condition is true
}

Executes one block if the condition is true and another block if it’s false.

Syntax:

if (condition) {
// Executes when condition is true
} else {
// Executes when condition is false
}

Tests multiple conditions in sequence. The block corresponding to the first true condition is executed. The final else (optional) executes if none of the preceding conditions are true.

Syntax:

if (condition1) {
// Executes if condition1 is true
} else if (condition2) {
// Executes if condition1 is false and condition2 is true
} else if (condition3) {
// Executes if conditions 1 & 2 are false and condition3 is true
} else {
// Executes if none of the above conditions are true
}

You can place if-else structures inside other if or else blocks to handle more complex conditions. Maintain readability using proper indentation.

Allows testing a variable for equality against a list of values (cases). More efficient than long if-else if chains for specific value comparisons.

Traditional switch (pre-Java 14):

switch (expression) {
case value1:
// Statements
break; // Important: exits switch
case value2:
// Statements
break;
// ... other cases
default: // Optional: executes if no case matches
// Statements
}

Modern switch (Expressions, Java 14+): Offers a more concise and less error-prone syntax using -> (arrow) labels and can be used as an expression that yields a value.

// Example using switch expression
int day = 3;
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday"; // Arrow label implies break
case 4 -> "Thursday";
case 5 -> "Friday";
default -> "Weekend or Invalid day";
}; // Semicolon needed for expression
System.out.println(dayName); // Output: Wednesday
// Example with multiple case labels and yield
int num = 2;
String result = switch (num) {
case 1, 3, 5 -> {
System.out.println("Odd number");
yield "Odd"; // yield used for returning value from block
}
case 2, 4 -> {
System.out.println("Even number");
yield "Even";
}
default -> "Unknown";
};

switch works with byte, short, char, int, their wrapper types, enum types, and String (since Java 7).

A method is a block of code that performs a specific task. It promotes code reusability and organization.

Method Signature Syntax:

accessModifier nonAccessModifiers(opt) returnType methodName(parameterList) throws ExceptionList(opt) {
// Method body: code to perform the task
// Optional: return statement if returnType is not void
}

Components of a method:

  • Access Modifier: (e.g., public, private) Controls visibility.
  • Non-Access Modifiers: (e.g., static, final) Provide other characteristics.
  • Return Type: The data type of the value the method returns (or void if it returns nothing).
  • Method Name: Identifier for the method (follows lowerCamelCase convention).
  • Parameter List: Comma-separated list of input variables (type and name) the method accepts. Can be empty (). Java uses pass-by-value semantics (copies of primitive values or references are passed).
  • Method Body: Contains the code statements enclosed in {}.
  • Throws Clause (Optional): Lists checked exceptions the method might throw.

Example Method:

/**
* Calculates the sum of two integers.
* @param num1 The first integer.
* @param num2 The second integer.
* @return The sum of num1 and num2.
*/
public int addNumbers(int num1, int num2) {
int sum = num1 + num2;
return sum;
}

Java is fundamentally object-oriented. Understanding classes and objects is essential.

  • Class: The blueprint defining attributes (fields/instance variables) and behaviors (methods).
  • Object: An instance of a class, created using the new keyword. Each object has its own state based on the values of its instance variables.

Example Car class:

public class Car {
// Instance variables (state)
String make;
String model;
int year;
// Constructor (special method for creating objects)
public Car(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}
// Method (behavior)
public void displayInfo() {
System.out.println("Car: " + year + " " + make + " " + model);
}
public static void main(String[] args) {
// Create Car objects (instances)
Car myCar1 = new Car("Toyota", "Camry", 2023);
Car myCar2 = new Car("Honda", "Civic", 2022);
// Call methods on objects
myCar1.displayInfo(); // Output: Car: 2023 Toyota Camry
myCar2.displayInfo(); // Output: Car: 2022 Honda Civic
}
}

Types of variables within a class context:

  • Local Variables: Inside methods/constructors/blocks.
  • Instance Variables: Declared in the class, outside methods. Each object has its own copy.
  • Class Variables (static): Declared with static. Shared among all objects of the class.

Exceptions are events that disrupt the normal flow of program execution (e.g., file not found, invalid input). Java provides mechanisms to handle them gracefully.

Code that might throw an exception is placed within a try block. A catch block follows to handle specific types of exceptions if they occur.

try {
// Code that might throw an exception (e.g., division by zero)
int result = 10 / 0;
} catch (ArithmeticException e) {
// Code to handle the ArithmeticException
System.err.println("Error: Division by zero! " + e.getMessage());
}

You can have multiple catch blocks to handle different exception types. Since Java 7, you can use a single catch block for multiple exception types using the | operator (multi-catch).

try {
// Code that might throw different exceptions
} catch (IOException | SQLException e) {
// Handle IOException or SQLException
System.err.println("I/O or SQL Error: " + e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
// Handle array index error
System.err.println("Array index out of bounds: " + e.getMessage());
} catch (Exception e) {
// Catch any other general exceptions (usually placed last)
System.err.println("An unexpected error occurred: " + e.getMessage());
}
  • Checked Exceptions: Exceptions that the compiler forces you to handle (either with try-catch or by declaring them with throws). Typically represent recoverable conditions external to the program (e.g., IOException, SQLException).
  • Unchecked Exceptions (Runtime Exceptions): Exceptions that usually result from programming errors (e.g., NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException). The compiler doesn’t require explicit handling, but they can still be caught.

If a method might throw a checked exception but doesn’t handle it with try-catch, it must declare the exception using the throws keyword in its signature. This passes the responsibility of handling the exception to the caller.

public void readFile(String fileName) throws IOException {
// Code that might throw IOException
}

Used to explicitly throw an exception object (usually a newly created one). Can be used to signal an error condition.

if (input < 0) {
throw new IllegalArgumentException("Input cannot be negative.");
}

A finally block, following try and any catch blocks, always executes, regardless of whether an exception occurred or was caught. It’s typically used for cleanup operations (e.g., closing files or network connections).

try {
// Risky code
} catch (Exception e) {
// Handle exception
} finally {
// Cleanup code that always runs
System.out.println("Executing finally block.");
}

Introduced in Java 7, this is the preferred way to handle resources that need to be closed (like file streams or database connections). It automatically closes resources declared within its parentheses, making finally blocks for resource closing often unnecessary and reducing boilerplate code.

// Example: Reading from a file
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
// 'reader' is automatically closed here, even if exceptions occur.

This quick guide covers the fundamentals. For a deeper understanding of Java, explore topics like the Collections Framework, Generics, Concurrency, I/O Streams, Lambdas, Streams API, and modules.