Java enforces a strict object-oriented structure: every source file must define exactly one public class, and the fileanme must match the class name (e.g., Main.java for class Main). Unlike C++, all functions—including main—must be declared inside a class.
Program Entry Point
The Java main method has a fixed signature and must reside within a class:
public class Main {
public static void main(String[] args) {
// application logic
}
}
This contrasts with C++, where main exists at global scope.
Method Definitions
In Java, helper methods used by main must be static because main itself is static:
public class Main {
public static void speak() {
System.out.println("666");
}
public static void main(String[] args) {
speak();
}
}
For non-static methods, instantiate the class first:
public class Person {
public void speak() {
System.out.println("666");
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.speak();
}
}
Packages
Packages act as namespaces and map directly to directory structures. A class in package util is declared as:
package util;
public class Person {
public void speak() {
System.out.println("666");
}
}
To use it from another package:
import util.Person;
public class Main {
public static void main(String[] args) {
Person p = new Person();
p.speak();
}
}
Standard naming uses reversed domain names (e.g., com.example.util). Classes in the same package or in java.lang don’t require explicit imports.
Primitive Types and Literals
Java has eight primitive types:
- Integer types:
byte,short,int,long - Floating-point:
float,double char(16-bit Unicode)boolean
Literals require suffixes for disambiguation:
long: appendL(e.g.,9999999999L)float: appendF(e.g.,10.1F)- Characters use single quotes (
'a'); strings use double quotes ("hello")
Unlike C++, Java does not allow implicit narrowing (e.g., int a = 1.1; is invalid).
Wrapper Classes and Autoboxing
Each primitive has a corresponding wrapper class (Integer, Double, etc.). These enable object semantics and support caching:
Integer,Byte,Short,Long: cache values in [-128, 127]Character: caches [0, 127]Boolean: returns canonicalTRUE/FALSE
Example:
Integer a = 40; // uses cached instance via Integer.valueOf(40)
Integer b = new Integer(40); // creates new object
System.out.println(a == b); // false — avoid == for value comparison
Always use .equals() for value comparison between wrapper objects.
Autoboxing (primitive ↔ wrapper) happens automatically but incurs performance cost:
Integer x = 10; // equivalent to Integer.valueOf(10)
int y = x; // equivalent to x.intValue()
Avoid unnecessary boxing in loops or performance-critical code.
Abritrary-Precision Arithmetic
Use BigDecimal for exact decimal arithmetic (e.g., financial calculations):
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.subtract(b)); // 0.1
Use BigInteger for integers beyond long range:
BigInteger big = new BigInteger("123456789012345678901234567890");
Input and Output
Output uses System.out.println():
System.out.println("Hello");
System.out.println(42);
Input uses Scanner:
import java.util.Scanner;
Scanner input = new Scanner(System.in);
int n = input.nextInt();
Enhanced Control Structures
Enhanced for-loop simplifies iteration:
int[] nums = {1, 2, 3};
for (int v : nums) {
System.out.println(v);
}
Switch expressions (Java 14+) allow concise assignment:
String day = switch (dayOfWeek) {
case 1 -> "Monday";
case 2 -> "Tuesday";
// ...
default -> "Invalid";
};
Reference vs. Primitive Types
Primitives store values directly; reference types store heap object addresses. All objects are created with new:
Person p = new Person(); // p holds a reference, like a C++ pointer
Java references are safer than C++ pointers—they cannot perform arithmetic and are garbage-collected.
Arrays
Arrays are objects with a .length field:
int[] arr = new int[5];
System.out.println(arr.length); // 5
Array access is bounds-checked; out-of-range access throws ArrayIndexOutOfBoundsException.
Initialization options:
int[] a = new int[]{1, 2, 3};
int[] b = {1, 2, 3}; // shorthand
Method Rules
Every non-void method must return a value on all control paths:
static boolean isValid(int x) {
if (x > 0) return true;
return false; // required — no implicit return
}
Varargs allow variable arguments (must be last parameter):
public static void log(String... messages) {
for (String msg : messages) {
System.out.println(msg);
}
}
Overloaded methods with fixed parameters take precedence over varargs versions.
The final Keyword
- Variable: assigned only once (like
constin C++) - Method: cannot be overridden
- Class: cannot be subclassed
Example:
public final class Constants {
public static final double PI = 3.14159;
}