Data Types
Java categorizes data types into two groups:1. Primitive Types
2. Reference Types
Primitive types directly store values, whereas reference types store references to objects located in heap memory.
Primitive Data Types
Java defines eight primitive data types.| Type | Size | Default Value | Range |
|---|---|---|---|
| byte | 8 bits | 0 | -128 to 127 |
| short | 16 bits | 0 | -32,768 to 32,767 |
| int | 32 bits | 0 | -231 to 231-1 |
| long | 64 bits | 0L | -263 to 263-1 |
| float | 32 bits | 0.0f | IEEE 754 |
| double | 64 bits | 0.0d | IEEE 754 |
| char | 16 bits | '\u0000' | Unicode character |
| boolean | JVM dependent | false | true or false |
int age = 30;
double salary = 75000.50;
char grade = 'A';
boolean active = true;
Reference Types
Reference types include classes, interfaces, arrays, enums, records, and annotations.String name = "John";
Employee employee = new Employee();
List<String> cities = new ArrayList<>();
A reference variable stores the memory address of an object, not the object itself. Reference variables can hold null.
Employee employee = null;
Dereferencing a null reference throws NullPointerException.
Primitive vs Reference Types
Primitive types have fixed memory size, store values directly, cannot be null, and are generally faster because no object allocation is required.Reference types store object references, can be null, support inheritance and polymorphism, and require heap allocation for objects.
Numeric Literals
Java supports decimal, binary, octal, and hexadecimal literals.int decimal = 100;
int binary = 0b1100100;
int octal = 0144;
int hexadecimal = 0x64;
Underscores improve readability.
long population = 8_500_000_000L;
Floating-Point Literals
Floating-point literals are double by default.double price = 99.99;
float discount = 10.5f;
Using a float literal without the f suffix results in a compilation error.
Character Literals
Characters use single quotes and represent Unicode characters.char letter = 'A';
char symbol = '$';
char unicode = '\u20B9';
Escape Sequences
Java supports several escape characters.System.out.println("Hello\nWorld");
System.out.println("Java\tProgramming");
System.out.println("\"Quoted\"");
System.out.println("\\");
Common escape sequences include: \n New line, \t Tab, " Double quote, ' Single quote, \ Backslash.
Variables
Variables are classified into three categories.1. Local Variables are declared inside methods and must be initialized before use.
2. Instance Variables belong to objects and receive default values.
3. Static Variables belong to the class and are shared by all objects.
class Employee {
static String company = "ABC";
String name;
void display() {
int age = 30;
System.out.println(company);
System.out.println(name);
System.out.println(age);
}
}
Default Values
Instance and static variables receive default values.int number = 0;
boolean active = false;
double salary = 0.0;
char grade = '\u0000';
Object reference = null;
Local variables never receive default values.
Type Conversion
Java supports implicit widening and explicit narrowing.1. Widening occurs automatically.
int number = 100;
long value = number;
double salary = value;
2. Narrowing requires explicit casting.
double price = 99.99;
int value = (int) price;
Output:
99
Narrowing may lose precision.
Type Casting
Reference types can also be cast.Animal animal = new Dog();
Dog dog = (Dog) animal;
Invalid casts throw ClassCastException.
Type Inference
Java supports local variable type inference using var.var name = "John";
var numbers = List.of(1, 2, 3);
The compiler infers the variable type during compilation. var can only be used for local variables.
Operators
Java operators are categorized as follows.- Arithmetic
- Unary
- Assignment
- Relational
- Logical
- Bitwise
- Shift
- Conditional
- Instanceof
Arithmetic Operators
Arithmetic operators perform mathematical operations.int a = 10;
int b = 3;
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b);
System.out.println(a / b);
System.out.println(a % b);
Integer division discards the fractional part.
System.out.println(10 / 3);
Output:
3
Unary Operators
Unary operators work on a single operand.int x = 5;
++x;
--x;
+x;
-x;
!true;
Increment and Decrement
Pre-increment modifies the value before evaluation.int x = 5;
System.out.println(++x);
Output:
6
Post-increment evaluates first and increments afterward.
int x = 5;
System.out.println(x++);
System.out.println(x);
Output:
5
6
Assignment Operators
int x = 10;
x += 5;
x -= 2;
x *= 3;
x /= 2;
x %= 4;
Compound assignment performs the operation and assignment together.
Relational Operators
Relational operators compare values.int a = 10;
int b = 20;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a >= b);
System.out.println(a <= b);
System.out.println(a == b);
System.out.println(a != b);
The result is always a boolean value.
Logical Operators
Logical operators combine boolean expressions.boolean a = true;
boolean b = false;
System.out.println(a && b);
System.out.println(a || b);
System.out.println(!a);
The operators && and || use short-circuit evaluation.
if (employee != null && employee.isActive()) {
}
The second expression executes only if required.
Bitwise Operators
Bitwise operators operate directly on bits.int a = 5;
int b = 3;
a & b;
a | b;
a ^ b;
~a;
These operators are commonly used in low-level programming and performance-sensitive applications.
Shift Operators
Shift operators move bits left or right.int number = 8;
number << 1;
number >> 1;
number >>> 1;
<< Left shift>> Signed right shift
>>> Unsigned right shift
Ternary Operator
The conditional operator provides a concise alternative to simple if-else statements.String result = age >= 18 ? "Adult" : "Minor";
The ternary operator returns a value and should be used only when it improves readability.
Operator Precedence
Java evaluates expressions according to predefined operator precedence. Parentheses should be used whenever precedence is not immediately obvious.int result = (a + b) * c;
Readable code is preferred over relying on operator precedence.
Conditional Statements
if Statement
The if statement executes code when a condition is true.if (age >= 18) {
System.out.println("Adult");
}
if-else Statement
if (marks >= 40) {
System.out.println("Pass");
} else {
System.out.println("Fail");
}
else-if Ladder
if (marks >= 90) {
System.out.println("A");
} else if (marks >= 80) {
System.out.println("B");
} else {
System.out.println("C");
}
Conditions are evaluated sequentially until one matches.
switch Statement
Modern Java supports both traditional and enhanced switch expressions. Traditional switch:switch (day) {
case 1:
System.out.println("Monday");
break;
default:
System.out.println("Invalid");
}
Enhanced switch:
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
default -> "Invalid";
};
Enhanced switch eliminates fall-through and improves readability.
Loops
for Loop
The for loop is used when the number of iterations is known.for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
Enhanced for Loop
The enhanced for loop iterates over arrays and collections.for (String city : cities) {
System.out.println(city);
}
It cannot modify the underlying collection structure.
while Loop
The while loop executes while the condition remains true.while (count > 0) {
count--;
}
Use while when the number of iterations is unknown.
do-while Loop
The do-while loop always executes at least once.do {
System.out.println(count);
} while (count > 0);
break Statement
The break statement immediately terminates the nearest loop or switch.for (int i = 0; i < 10; i++) {
if (i == 5) {
break;
}
}
continue Statement
The continue statement skips the current iteration.for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue;
}
System.out.println(i);
}
Labeled break and continue
Java supports labeled statements for nested loops.outer:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (j == 2) {
break outer;
}
}
}
Labeled statements should be used sparingly because they often reduce readability.
Pattern Matching in switch
Modern Java extends switch to support pattern matching.Object value = "Java";
switch (value) {
case String s -> System.out.println(s.length());
case Integer i -> System.out.println(i * 2);
default -> System.out.println("Unknown");
}
Pattern matching eliminates many explicit casts and instanceof checks.
Expression Statements
Java expressions can produce values, while statements perform actions.int x = 10 + 20;
System.out.println(x);
Understanding this distinction helps when working with lambda expressions, switch expressions, and functional APIs.
Final Notes
Java provides a rich type system and a comprehensive set of operators and control flow constructs.Choosing appropriate data types, avoiding unnecessary type conversions, understanding operator precedence, using short-circuit logical operators, preferring enhanced switch expressions, and selecting the correct looping construct improve readability, correctness, and performance.