The ultimate deep-dive guide for mastering Java fundamentals with in-depth explanations and practical examples
π Table of Contents
- Introduction
- Understanding Java's Architecture
- Data Types & Variables
- Operato...
The ultimate deep-dive guide for mastering Java fundamentals with in-depth explanations and practical examples
π Table of Contents
- Introduction
- Understanding Java's Architecture
- Data Types & Variables
- Operators in Java
- Control Flow Statements
- Object-Oriented Programming
- Strings Deep Dive
- Arrays Explained
π― Introduction
Java is one of the most popular programming languages, powering everything from Android apps to enterprise systems. Understanding Java deeply is crucial for building robust applications and succeeding in technical interviews.
This comprehensive guide will take you from basics to advanced concepts with clear explanations and practical examples.
Who This Guide Is For:
- Developers preparing for technical interviews
- Beginners wanting to understand Java fundamentals
- Intermediate developers looking to fill knowledge gaps
- Anyone needing a comprehensive Java reference
What Makes This Different:
β
In-depth explanations with real-world context
β
Memory diagrams and visual representations
β
Common pitfalls and best practices
β
Performance considerations
β
Code examples you can run immediately
β
Practice questions to test your understanding
Reading Time: 45-60 minutes
Difficulty: Beginner to Advanced
ποΈ Understanding Javaβs Architecture
The Big Three: JVM, JRE, JDK
Let me start with a question that's often asked: junior interview:
**Explain the difference between JVM, JRE, and JDK."
Let's break this down. Here's a comprehensive answer:
JVM (Java Virtual Machine)
Simple Answer: The runtime engine that executes Java bytecode.
Deep Answer: The JVM is an abstract computing machine with three key responsibilities:
-
Loading - Reads
.classfiles - Verification - Ensures bytecode is valid and safe
- Execution - Runs the bytecode using an interpreter or JIT compiler
βββββββββββββββββββββββββββββββββββββββ
β JVM ARCHITECTURE β
βββββββββββββββββββββββββββββββββββββββ€
β Class Loader Subsystem β
β ββ Bootstrap ClassLoader β
β ββ Extension ClassLoader β
β ββ Application ClassLoader β
βββββββββββββββββββββββββββββββββββββββ€
β Runtime Data Areas β
β ββ Method Area (Metadata) β
β ββ Heap (Objects) β
β ββ Stack (Method calls) β
β ββ PC Registers β
β ββ Native Method Stack β
βββββββββββββββββββββββββββββββββββββββ€
β Execution Engine β
β ββ Interpreter β
β ββ JIT Compiler β
β ββ Garbage Collector β
βββββββββββββββββββββββββββββββββββββββ
Key Key Insight: The JVM is platform-independent but implementation-specific. Different vendors (Oracle, OpenJDK, GraalVM) have different JVM implementations.
JRE (Java Runtime Environment)
Simple Answer: JVM + Libraries needed to run Java applications.
Deep Answer:
JRE = JVM + Core Libraries (java.lang, java.util, etc.) + Configuration files
The JRE provides:
- Class libraries (rt.jar, charsets.jar)
- Property files (default character encodings)
- Security policies
- DLL files (Windows) or SO files (Linux)
Common Trap Question: "Can you develop Java applications with only JRE?"
Explanation: No. JRE is for running applications. You need JDK for development.
JDK (Java Development Kit)
Simple Answer: JRE + Development tools.
Deep Answer:
JDK = JRE + Development Tools + Compiler (javac) + Debugger + JavaDoc
The JDK includes:
-
javac- Compiler -
java- Launcher -
javadoc- Documentation generator -
jar- Archive tool -
jdb- Debugger -
jconsole- Monitoring tool
Relationship:
βββββββββββββββββββββββββββββββββββββββ
β JDK β
β βββββββββββββββββββββββββββββββββ β
β β JRE β β
β β βββββββββββββββββββββββββββ β β
β β β JVM β β β
β β βββββββββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββ
How Java Actually Works
**Walk me through what happens when you run java HelloWorld."
Here's the complete flow:
Step 1: Write Code
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Step 2: Compilation
javac HelloWorld.java
What happens internally:
- Lexical Analysis - Breaks code into tokens
- Syntax Analysis - Checks grammar
- Semantic Analysis - Type checking
-
Bytecode Generation - Creates
.classfile
Key Point: Java bytecode is platform-independent. The same .class file runs on Windows, Linux, Mac.
Step 3: Execution
java HelloWorld
What happens internally:
- Class Loading
Bootstrap ClassLoader β Loads core Java classes (java.lang.*)
Extension ClassLoader β Loads extension classes (javax.*)
Application ClassLoader β Loads our HelloWorld.class
-
Bytecode Verification
- Stack overflow/underflow checks
- Type safety verification
- Access control checks
-
Execution
- Interpreter reads bytecode line by line
- JIT compiler converts hot code to native machine code
- Garbage collector manages memory
Memory Layout During Execution:
βββββββββββββββββββββββββββββββββββββββ
β HEAP β
β "Hello, World!" String object β
β System object β
βββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββ
β STACK β
β main() method frame β
β ββ args: String[] β
β ββ local variables β
βββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββ
β METHOD AREA β
β HelloWorld class metadata β
β main() method bytecode β
βββββββββββββββββββββββββββββββββββββββ
Common Question: "Why is Java called 'Platform Independent but Platform Dependent'?"
Explanation:
- Platform Independent: Bytecode runs on any platform with JVM
- Platform Dependent: JVM itself is platform-specific (different JVM for Windows/Linux/Mac)
π Data Types & Variables
The Two Categories
**Explain primitive vs non-primitive types. Why does Java have both?"
Primitive Types (Stored in Stack)
Java has 8 primitive types. Let me show you the complete picture:
| Type | Size | Range | Default | Wrapper Class |
|---|---|---|---|---|
byte |
8-bit | -128 to 127 | 0 | Byte |
short |
16-bit | -32,768 to 32,767 | 0 | Short |
int |
32-bit | -2Β³ΒΉ to 2Β³ΒΉ-1 | 0 | Integer |
long |
64-bit | -2βΆΒ³ to 2βΆΒ³-1 | 0L | Long |
float |
32-bit | IEEE 754 | 0.0f | Float |
double |
64-bit | IEEE 754 | 0.0d | Double |
char |
16-bit | 0 to 65,535 | '\u0000' | Character |
boolean |
1-bit* | true/false | false | Boolean |
Important Note: boolean size is JVM-dependent. It's treated as int (4 bytes) in arrays, but 1 byte standalone.
Deep Dive: Integer Types
public class IntegerTypes {
public static void main(String[] args) {
// Byte
byte b = 127;
// byte b2 = 128; // β Compilation error: out of range
<span class="c1">// Integer literals</span>
<span class="kt">int</span> <span class="n">decimal</span> <span class="o">=</span> <span class="mi">100</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">binary</span> <span class="o">=</span> <span class="mb">0b1100100</span><span class="o">;</span> <span class="c1">// Binary (Java 7+)</span>
<span class="kt">int</span> <span class="n">octal</span> <span class="o">=</span> <span class="mo">0144</span><span class="o">;</span> <span class="c1">// Octal</span>
<span class="kt">int</span> <span class="n">hex</span> <span class="o">=</span> <span class="mh">0x64</span><span class="o">;</span> <span class="c1">// Hexadecimal</span>
<span class="c1">// Underscores for readability (Java 7+)</span>
<span class="kt">int</span> <span class="n">million</span> <span class="o">=</span> <span class="mi">1_000_000</span><span class="o">;</span>
<span class="kt">long</span> <span class="n">creditCard</span> <span class="o">=</span> <span class="mi">1234_5678_9012_3456L</span><span class="o">;</span>
<span class="c1">// Type promotion</span>
<span class="kt">byte</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">10</span><span class="o">;</span>
<span class="kt">byte</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span>
<span class="c1">// byte z = x + y; // β Error: result is int</span>
<span class="kt">int</span> <span class="n">z</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="o">;</span> <span class="c1">// β
Correct</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"All equal: "</span> <span class="o">+</span> <span class="o">(</span><span class="n">decimal</span> <span class="o">==</span> <span class="n">binary</span> <span class="o">&&</span> <span class="n">binary</span> <span class="o">==</span> <span class="n">octal</span> <span class="o">&&</span> <span class="n">octal</span> <span class="o">==</span> <span class="n">hex</span><span class="o">));</span>
<span class="o">}</span>
}
Common Mistake: "Why does byte x = 10; byte y = 20; byte z = x + y; fail to compile?"
Explanation: In Java, operations on types smaller than int are promoted to int. So x + y returns an int, which cannot be assigned to byte without explicit casting.
Floating-Point Types
public class FloatingPoint {
public static void main(String[] args) {
// Float requires 'f' suffix
float f1 = 3.14f;
// float f2 = 3.14; // β Error: double cannot be converted to float
<span class="c1">// Double is default for decimal literals</span>
<span class="kt">double</span> <span class="n">d1</span> <span class="o">=</span> <span class="mf">3.14</span><span class="o">;</span>
<span class="kt">double</span> <span class="n">d2</span> <span class="o">=</span> <span class="mf">3.14d</span><span class="o">;</span> <span class="c1">// 'd' is optional</span>
<span class="c1">// Scientific notation</span>
<span class="kt">double</span> <span class="n">scientist</span> <span class="o">=</span> <span class="mf">1.23e5</span><span class="o">;</span> <span class="c1">// 123000.0</span>
<span class="c1">// Special values</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Positive Infinity: "</span> <span class="o">+</span> <span class="o">(</span><span class="mf">1.0</span> <span class="o">/</span> <span class="mf">0.0</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Negative Infinity: "</span> <span class="o">+</span> <span class="o">(-</span><span class="mf">1.0</span> <span class="o">/</span> <span class="mf">0.0</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"NaN: "</span> <span class="o">+</span> <span class="o">(</span><span class="mf">0.0</span> <span class="o">/</span> <span class="mf">0.0</span><span class="o">));</span>
<span class="c1">// Precision issues (CRITICAL FOR INTERVIEWS)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="mf">0.1</span> <span class="o">+</span> <span class="mf">0.2</span><span class="o">);</span> <span class="c1">// 0.30000000000000004</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="mf">0.1</span> <span class="o">+</span> <span class="mf">0.2</span> <span class="o">==</span> <span class="mf">0.3</span><span class="o">);</span> <span class="c1">// false β οΈ</span>
<span class="c1">// Solution: Use BigDecimal for financial calculations</span>
<span class="o">}</span>
}
Critical Question: Point: Never use float or double for financial calculations due to precision errors. Use BigDecimal instead.
Character Type
public class CharacterType {
public static void main(String[] args) {
// Different ways to declare char
char c1 = 'A';
char c2 = 65; // ASCII value
char c3 = '\u0041'; // Unicode
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">c1</span> <span class="o">==</span> <span class="n">c2</span> <span class="o">&&</span> <span class="n">c2</span> <span class="o">==</span> <span class="n">c3</span><span class="o">);</span> <span class="c1">// true</span>
<span class="c1">// Char is essentially a 16-bit unsigned integer</span>
<span class="kt">char</span> <span class="n">ch</span> <span class="o">=</span> <span class="sc">'A'</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ch</span> <span class="o">+</span> <span class="mi">1</span><span class="o">);</span> <span class="c1">// 66 (promoted to int)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">((</span><span class="kt">char</span><span class="o">)(</span><span class="n">ch</span> <span class="o">+</span> <span class="mi">1</span><span class="o">));</span> <span class="c1">// 'B'</span>
<span class="c1">// Unicode support</span>
<span class="kt">char</span> <span class="n">emoji</span> <span class="o">=</span> <span class="sc">'π'</span><span class="o">;</span> <span class="c1">// Works in Java!</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"Emoji: "</span> <span class="o">+</span> <span class="n">emoji</span><span class="o">);</span>
<span class="o">}</span>
}
Boolean Type
public class BooleanType {
public static void main(String[] args) {
boolean flag = true;
<span class="c1">// β These DON'T work in Java (unlike C/C++)</span>
<span class="c1">// boolean b1 = 1;</span>
<span class="c1">// boolean b2 = 0;</span>
<span class="c1">// if (1) { }</span>
<span class="c1">// β
Only true/false allowed</span>
<span class="k">if</span> <span class="o">(</span><span class="n">flag</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"This works!"</span><span class="o">);</span>
<span class="o">}</span>
<span class="c1">// Size consideration</span>
<span class="kt">boolean</span><span class="o">[]</span> <span class="n">boolArray</span> <span class="o">=</span> <span class="k">new</span> <span class="kt">boolean</span><span class="o">[</span><span class="mi">100</span><span class="o">];</span>
<span class="c1">// Each element takes 1 byte (8 bits) in array</span>
<span class="c1">// But boolean variable size is JVM-dependent</span>
<span class="o">}</span>
}
Non-Primitive Types (Reference Types)
Everything else is a non-primitive type:
- Classes
- Interfaces
- Arrays
- Enums
- Annotations
public class ReferenceTypes {
public static void main(String[] args) {
// Reference types store addresses, not values
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span><span class="o">);</span> <span class="c1">// true (same reference in String pool)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s1</span> <span class="o">==</span> <span class="n">s3</span><span class="o">);</span> <span class="c1">// false (different objects)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">s1</span><span class="o">.</span><span class="na">equals</span><span class="o">(</span><span class="n">s3</span><span class="o">));</span> <span class="c1">// true (same content)</span>
<span class="c1">// Memory layout</span>
<span class="cm">/*
STACK:
s1 β [reference to "Hello" in String pool]
s2 β [reference to "Hello" in String pool] (same as s1)
s3 β [reference to new String object in heap]
HEAP:
String pool: "Hello" β (s1 and s2 point here)
Regular heap: new String("Hello") β (s3 points here)
*/</span>
<span class="o">}</span>
}
Variable Types & Scope
public class VariableTypes {
// 1. Instance Variables (Non-static fields)
private int instanceVar = 10;
<span class="c1">// 2. Class Variables (Static fields)</span>
<span class="kd">private</span> <span class="kd">static</span> <span class="kt">int</span> <span class="n">classVar</span> <span class="o">=</span> <span class="mi">20</span><span class="o">;</span>
<span class="c1">// 3. Local Variables</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">method</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">localVar</span> <span class="o">=</span> <span class="mi">30</span><span class="o">;</span>
<span class="c1">// 4. Parameters</span>
<span class="n">processData</span><span class="o">(</span><span class="n">localVar</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">processData</span><span class="o">(</span><span class="kt">int</span> <span class="n">parameter</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">parameter</span><span class="o">);</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">VariableTypes</span> <span class="n">obj1</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">VariableTypes</span><span class="o">();</span>
<span class="nc">VariableTypes</span> <span class="n">obj2</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">VariableTypes</span><span class="o">();</span>
<span class="c1">// Instance variables are per-object</span>
<span class="n">obj1</span><span class="o">.</span><span class="na">instanceVar</span> <span class="o">=</span> <span class="mi">100</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj2</span><span class="o">.</span><span class="na">instanceVar</span><span class="o">);</span> <span class="c1">// 10 (unchanged)</span>
<span class="c1">// Class variables are shared across all instances</span>
<span class="n">obj1</span><span class="o">.</span><span class="na">classVar</span> <span class="o">=</span> <span class="mi">200</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj2</span><span class="o">.</span><span class="na">classVar</span><span class="o">);</span> <span class="c1">// 200 (changed!)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="nc">VariableTypes</span><span class="o">.</span><span class="na">classVar</span><span class="o">);</span> <span class="c1">// 200</span>
<span class="o">}</span>
}
Memory Layout:
HEAP:
βββββββββββββββββββββββ
β VariableTypes obj1 β
β instanceVar: 100 β
βββββββββββββββββββββββ
βββββββββββββββββββββββ
β VariableTypes obj2 β
β instanceVar: 10 β
βββββββββββββββββββββββ
METHOD AREA:
βββββββββββββββββββββββ
β VariableTypes class β
β classVar: 200 β β Shared by all instances
βββββββββββββββββββββββ
Variable Initialization
public class Initialization {
// Instance variables - Default initialized
int x; // 0
boolean flag; // false
String str; // null
<span class="c1">// Local variables - NOT default initialized</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">method</span><span class="o">()</span> <span class="o">{</span>
<span class="kt">int</span> <span class="n">y</span><span class="o">;</span>
<span class="c1">// System.out.println(y); // β Error: variable not initialized</span>
<span class="n">y</span> <span class="o">=</span> <span class="mi">10</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">y</span><span class="o">);</span> <span class="c1">// β
Now it works</span>
<span class="o">}</span>
<span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="nc">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
<span class="nc">Initialization</span> <span class="n">obj</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Initialization</span><span class="o">();</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">x</span><span class="o">);</span> <span class="c1">// 0 (default)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">flag</span><span class="o">);</span> <span class="c1">// false (default)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">obj</span><span class="o">.</span><span class="na">str</span><span class="o">);</span> <span class="c1">// null (default)</span>
<span class="o">}</span>
}
Common Question: "Why are instance variables default-initialized but local variables aren't?"
Explanation:
- Instance variables are part of object state and must have predictable values. JVM zero-initializes them.
- Local variables are temporary and forcing initialization would hurt performance. Compiler ensures they're assigned before use.
π§ Operators in Java
Operator Precedence (High to Low)
public class OperatorPrecedence {
public static void main(String[] args) {
int result;
<span class="c1">// 1. Postfix: expr++, expr--</span>
<span class="c1">// 2. Unary: ++expr, --expr, +expr, -expr, !</span>
<span class="c1">// 3. Multiplicative: *, /, %</span>
<span class="c1">// 4. Additive: +, -</span>
<span class="c1">// 5. Shift: <<, >>, >>></span>
<span class="c1">// 6. Relational: <, >, <=, >=, instanceof</span>
<span class="c1">// 7. Equality: ==, !=</span>
<span class="c1">// 8. Bitwise AND: &</span>
<span class="c1">// 9. Bitwise XOR: ^</span>
<span class="c1">// 10. Bitwise OR: |</span>
<span class="c1">// 11. Logical AND: &&</span>
<span class="c1">// 12. Logical OR: ||</span>
<span class="c1">// 13. Ternary: ? :</span>
<span class="c1">// 14. Assignment: =, +=, -=, *=, /=, %=, etc.</span>
<span class="c1">// Tricky example</span>
<span class="n">result</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">+</span> <span class="mi">3</span> <span class="o">*</span> <span class="mi">2</span><span class="o">;</span> <span class="c1">// 16 (not 26)</span>
<span class="n">result</span> <span class="o">=</span> <span class="o">(</span><span class="mi">10</span> <span class="o">+</span> <span class="mi">3</span><span class="o">)</span> <span class="o">*</span> <span class="mi">2</span><span class="o">;</span> <span class="c1">// 26</span>
<span class="n">result</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">/</span> <span class="mi">3</span> <span class="o">*</span> <span class="mi">3</span><span class="o">;</span> <span class="c1">// 9 (not 10!)</span>
<span class="c1">// Explanation: (10/3)*3 = 3*3 = 9 (integer division)</span>
<span class="o">}</span>
}
Unary Operators (++ and β)
public class UnaryOperators {
public static void main(String[] args) {
int x = 5;
<span class="c1">// Pre-increment: Increment THEN use</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(++</span><span class="n">x</span><span class="o">);</span> <span class="c1">// 6 (x becomes 6, then prints 6)</span>
<span class="c1">// Post-increment: Use THEN increment</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">x</span><span class="o">++);</span> <span class="c1">// 5 (prints 5, then x becomes 6)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">x</span><span class="o">);</span> <span class="c1">// 6</span>
<span class="c1">// Complex example (Question: Favorite)</span>
<span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="o">++</span><span class="n">a</span> <span class="o">+</span> <span class="n">a</span><span class="o">++</span> <span class="o">+</span> <span class="n">a</span><span class="o">--</span> <span class="o">+</span> <span class="o">--</span><span class="n">a</span><span class="o">;</span>
<span class="cm">/*
Step by step:
1. ++a β a=6, use 6 β expression: 6
2. a++ β use 6, a=7 β expression: 6+6 = 12
3. a-- β use 7, a=6 β expression: 12+7 = 19
4. --a β a=5, use 5 β expression: 19+5 = 24
Final: b=24, a=5
*/</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"b = "</span> <span class="o">+</span> <span class="n">b</span> <span class="o">+</span> <span class="s">", a = "</span> <span class="o">+</span> <span class="n">a</span><span class="o">);</span> <span class="c1">// b = 24, a = 5</span>
<span class="o">}</span>
}
Common Mistake: Never use multiple increment/decrement operators on same variable in one expression. It's undefined behavior in some cases.
Bitwise Operators
public class BitwiseOperators {
public static void main(String[] args) {
int a = 5; // 0101 in binary
int b = 3; // 0011 in binary
<span class="c1">// AND (&): Both bits must be 1</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span> <span class="o">&</span> <span class="n">b</span><span class="o">);</span> <span class="c1">// 1 (0001)</span>
<span class="c1">// OR (|): At least one bit must be 1</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span> <span class="o">|</span> <span class="n">b</span><span class="o">);</span> <span class="c1">// 7 (0111)</span>
<span class="c1">// XOR (^): Bits must be different</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">a</span> <span class="o">^</span> <span class="n">b</span><span class="o">);</span> <span class="c1">// 6 (0110)</span>
<span class="c1">// NOT (~): Flip all bits</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(~</span><span class="n">a</span><span class="o">);</span> <span class="c1">// -6 (two's complement)</span>
<span class="c1">// Left shift (<<): Multiply by 2^n</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="mi">5</span> <span class="o"><<</span> <span class="mi">2</span><span class="o">);</span> <span class="c1">// 20 (5 * 2^2)</span>
<span class="c1">// Right shift (>>): Divide by 2^n (signed)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="mi">20</span> <span class="o">>></span> <span class="mi">2</span><span class="o">);</span> <span class="c1">// 5 (20 / 2^2)</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(-</span><span class="mi">20</span> <span class="o">>></span> <span class="mi">2</span><span class="o">);</span> <span class="c1">// -5 (sign bit preserved)</span>
<span class="c1">// Unsigned right shift (>>>): Fill with zeros</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(-</span><span class="mi">20</span> <span class="o">>>></span> <span class="mi">2</span><span class="o">);</span> <span class="c1">// Large positive number</span>
<span class="c1">// Practical use: Check if number is even/odd</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"5 is odd: "</span> <span class="o">+</span> <span class="o">((</span><span class="mi">5</span> <span class="o">&</span> <span class="mi">1</span><span class="o">)</span> <span class="o">==</span> <span class="mi">1</span><span class="o">));</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"4 is even: "</span> <span class="o">+</span> <span class="o">((</span><span class="mi">4</span> <span class="o">&</span> <span class="mi">1</span><span class="o">)</span> <span class="o">==</span> <span class="mi">0</span><span class="o">));</span>
<span class="o">}</span>
}
Common Question: "How to swap two numbers without temp variable?"
public static void swap(int a, int b) {
System.out.println("Before: a=" + a + ", b=" + b);
<span class="n">a</span> <span class="o">=</span> <span class="n">a</span> <span class="o">^</span> <span class="n">b</span><span class="o">;</span> <span class="c1">// a = a XOR b</span>
<span class="n">b</span> <span class="o">=</span> <span class="n">a</span> <span class="o">^</span> <span class="n">b</span><span class="o">;</span> <span class="c1">// b = (a XOR b) XOR b = a</span>
<span class="n">a</span> <span class="o">=</span> <span class="n">a</span> <span class="o">^</span> <span class="n">b</span><span class="o">;</span> <span class="c1">// a = (a XOR b) XOR a = b</span>
<span class="nc">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">"After: a="</span> <span class="o">+</span> <span class="n">a</span> <span class="o">+</span> <span class="s">", b="</span> <span class="o">+</span> <span class="n">b</span><span class="o">);</span>
}
Short-Circuit Operators
public class ShortCircuit {
public static void main(String[] args) {
int x = 0;
<span class="c1">// Logical AND (&&) - Short circuits if first is false</span>
<span class="k">if</span> <span class="o">(</span><span class="kc">false</span> <span class="o">&&</span> <span class="o">++</span><span class="n">x</span> <span class="o">></span> <span class="mi">0</span><span class="o">)</span> <span class="o">{</span>
