Welcome back, future Java master! In our last chapter, we got your Java Development Kit (JDK) set up (we’re using JDK 25, the latest stable release as of September 2025, though JDK 21 remains the current Long-Term Support, or LTS, version), and you even wrote your very first “Hello, World!” program. That was a fantastic start! If you haven’t done that yet, please hop back to Chapter 1 and get yourself sorted.
Now that we know how to make Java say something, it’s time to teach it how to remember things and do calculations. Think of it like learning to speak a language: “Hello, World!” is a simple phrase, but to have a real conversation, you need words (data), ways to store them (variables), and ways to combine them (operators). That’s exactly what we’ll be tackling today!
By the end of this chapter, you’ll understand the fundamental concepts of variables (where you store information), data types (what kind of information you can store), and operators (how you manipulate that information). These are the absolute bedrock of any programming language, and mastering them will unlock your ability to write much more dynamic and useful programs. Ready to dive in? Let’s go!
2.1 Variables: Your Program’s Memory Boxes
Imagine you’re baking a cake. You need to keep track of the amount of flour, sugar, and eggs. You wouldn’t just dump them all into one pile, right? You’d put them in separate, labeled containers. In programming, variables are exactly like those labeled containers! They are names that refer to a storage location in your computer’s memory, where you can store different pieces of information.
Every variable has three main characteristics:
- A Name: How you refer to it (e.g.,
flourAmount,sugarCups). - A Type: What kind of data it can hold (e.g., whole numbers, decimal numbers, text).
- A Value: The actual data stored inside (e.g.,
2for flourAmount,"all-purpose"for flourType).
2.1.1 Declaring and Initializing Variables
Before you can use a variable, you need to tell Java about it. This is called declaring a variable. You specify its type and its name.
Then, you often give it an initial value, which is called initializing the variable.
Let’s see this in action. Open your HelloWorld.java file (or create a new VariablesDemo.java file if you prefer to keep things separate) and add the following lines inside your main method:
// Inside your public static void main(String[] args) method
// 1. Declaring a variable:
int myFirstNumber;
// 2. Initializing the variable (assigning a value):
myFirstNumber = 10;
// 3. Declaring and initializing in one go (very common!):
int mySecondNumber = 25;
// Let's print them out to see what's inside!
System.out.println("My first number is: " + myFirstNumber);
System.out.println("My second number is: " + mySecondNumber);
Explanation:
int myFirstNumber;: Here, we declare a variable namedmyFirstNumber. Theintkeyword tells Java that this variable will hold a whole number (an integer).myFirstNumber = 10;: This line initializesmyFirstNumberby assigning it the value10. The=symbol is the assignment operator.int mySecondNumber = 25;: This is the more common way: declaring and initializing a variable in a single line. It saves space and is often clearer.System.out.println(...): You’ve seen this before! We’re using it to print the values stored in our variables to the console. Notice how we can combine text (aString) with a variable’s value using the+operator – this is called string concatenation, and it’s super useful for showing variable values.
Go ahead, compile and run your code! You should see:
My first number is: 10
My second number is: 25
2.1.2 Variable Naming Rules & Best Practices
Just like in real life, good labels make things easier to understand. Java has rules and best practices for naming variables:
- Must start with: A letter (a-z, A-Z), an underscore (
_), or a dollar sign ($). (Starting with$or_is generally discouraged for regular variables, but you might see it in generated code or special contexts). - Cannot start with: A number.
- Can contain: Letters, numbers, underscores, and dollar signs.
- Cannot be: A Java keyword (like
int,public,class,void). - Case-sensitive:
myNumberis different frommynumber. - Best Practice (CamelCase): For multi-word variable names, start the first word with a lowercase letter and capitalize the first letter of subsequent words (e.g.,
totalStudentCount,userAge). This is called “camelCase” and it’s the standard in Java. - Be Descriptive: Choose names that clearly indicate the variable’s purpose.
ageis better thana,firstNameis better thanfn.
2.1.3 Constants with final
Sometimes, you have a value that should never change during your program’s execution, like the value of Pi or a maximum number of attempts. For these, you use the final keyword. A final variable can only be assigned a value once.
// Add this to your main method
final double PI = 3.14159; // Declaring a constant
// PI = 3.14; // If you uncomment this line, Java will give you a compile-time error!
System.out.println("The value of Pi is: " + PI);
Explanation:
final double PI = 3.14159;: Thefinalkeyword makesPIa constant. By convention, constant names are written inALL_CAPSwith underscores separating words.- If you try to reassign
PIafter its initial assignment, the Java compiler will prevent you, which is a great way to catch errors early!
2.2 Data Types: What Kind of Data Are We Storing?
Just as you wouldn’t store water in a flour bag, you need to tell Java what kind of data each variable will hold. This is where data types come in. Java is a “statically typed” language, meaning you must declare the type of a variable before you use it. This helps Java allocate the right amount of memory and prevents many common programming errors.
Java’s data types fall into two main categories:
- Primitive Data Types: These are the basic building blocks, storing simple values directly.
- Reference Data Types: These store references (addresses) to objects in memory. We’ll touch on
Stringhere, but dive much deeper into objects later.
2.2.1 Primitive Data Types
Java has 8 primitive data types, which are categorized by the type of value they hold:
- Whole Numbers (Integers):
byte: Very small whole numbers (-128 to 127).short: Small whole numbers (-32,768 to 32,767).int: The most commonly used integer type (around -2 billion to 2 billion). This is your go-to for whole numbers.long: Very large whole numbers (requiresLsuffix, e.g.,10000000000L).
- Decimal Numbers (Floating-Point):
float: Single-precision decimal numbers (requiresfsuffix, e.g.,3.14f).double: Double-precision decimal numbers. This is your go-to for decimal numbers and is more precise thanfloat.
- Characters:
char: A single character (e.g.,'A','7','@'). Enclosed in single quotes.
- Boolean:
boolean: Representstrueorfalse. Essential for logic and decision-making.
Let’s add some examples to your main method:
// Inside your public static void main(String[] args) method
// --- Primitive Data Types ---
// Integer types
byte smallNumber = 100;
int normalNumber = 1_000_000; // Underscores for readability in large numbers (JDK 7+)
long veryBigNumber = 1234567890123L; // Note the 'L' suffix for long
System.out.println("Byte: " + smallNumber);
System.out.println("Int: " + normalNumber);
System.out.println("Long: " + veryBigNumber);
// Floating-point types
float preciseFloat = 3.14159f; // Note the 'f' suffix for float
double veryPreciseDouble = 3.14159265359;
System.out.println("Float: " + preciseFloat);
System.out.println("Double: " + veryPreciseDouble);
// Character type
char initial = 'J'; // Single quotes for a single character
System.out.println("Initial: " + initial);
// Boolean type
boolean isJavaFun = true;
boolean isCoffeeCold = false;
System.out.println("Is Java fun? " + isJavaFun);
System.out.println("Is coffee cold? " + isCoffeeCold);
Explanation:
- We’ve declared and initialized variables for each of the main primitive types.
- Notice the
Lsuffix forlongandfsuffix forfloat. Without these, Java would treat123...as anint(potentially causing an overflow if too large) and3.14as adoubleby default. - The underscores in
1_000_000are purely for human readability and were introduced in JDK 7. Java ignores them. charuses single quotes,booleanuses the keywordstrueorfalse.
For more details on primitive data types, you can always refer to the official Oracle documentation: Primitive Data Types (JDK 25)
2.2.2 Reference Data Types: An Introduction to String
While primitive types store simple values directly, reference types (also called object types) store references to objects. Think of a reference as an address to a house, rather than the house itself. The most common reference type you’ll encounter immediately is String.
A String is used to store sequences of characters (text). Unlike char which holds a single character, String can hold words, sentences, or even entire documents.
// Add this to your main method
// --- Reference Data Type: String ---
String greeting = "Hello, Java learners!"; // Double quotes for String literals
String programmingLanguage = "Java";
String message = greeting + " Welcome to " + programmingLanguage + "!";
System.out.println(message);
Explanation:
String greeting = "Hello, Java learners!";: We declare a variablegreetingof typeStringand assign it a text value. NoticeStringstarts with a capitalS– this is a strong hint that it’s a class (an object type), not a primitive.String message = greeting + " Welcome to " + programmingLanguage + "!";: We’re concatenating multiple strings and variables together using the+operator to form a newString. This is a powerful and common operation.
Compile and run your code again! You’ll see all your variable values printed.
2.3 Operators: Performing Actions on Data
Now that we know how to store data, how do we do things with it? That’s the job of operators! Operators are special symbols that tell the compiler to perform specific mathematical, relational, or logical operations and produce a result.
2.3.1 Arithmetic Operators
These are the ones you remember from math class!
+(Addition)-(Subtraction)*(Multiplication)/(Division)%(Modulo - returns the remainder of a division)
// Add this to your main method
// --- Arithmetic Operators ---
int num1 = 10;
int num2 = 3;
int sum = num1 + num2;
int difference = num1 - num2;
int product = num1 * num2;
int quotient = num1 / num2; // Watch out for integer division!
int remainder = num1 % num2;
System.out.println("\n--- Arithmetic Operations ---");
System.out.println("Sum: " + sum); // Expected: 13
System.out.println("Difference: " + difference); // Expected: 7
System.out.println("Product: " + product); // Expected: 30
System.out.println("Quotient (int): " + quotient); // Expected: 3 (not 3.33! Why? See Pitfalls!)
System.out.println("Remainder: " + remainder); // Expected: 1 (10 divided by 3 is 3 with 1 left over)
// Using double for accurate division
double dNum1 = 10.0;
double dNum2 = 3.0;
double preciseQuotient = dNum1 / dNum2;
System.out.println("Quotient (double): " + preciseQuotient); // Expected: 3.333...
Explanation:
- Most of these are straightforward.
- Integer Division: When you divide two
inttypes, Java performs integer division, meaning it truncates (chops off) any decimal part, resulting in anint.10 / 3gives3, not3.33. To get a precise decimal result, at least one of the operands must be adoubleorfloat. - Modulo (
%): This is super useful for checking if a number is even/odd (ifnum % 2 == 0, it’s even) or for tasks like cycling through a fixed number of items.
2.3.2 Assignment Operators
You’ve already met the basic assignment operator =. But Java offers shorthand operators that combine an arithmetic operation with assignment:
=(Assign)+=(Add and assign:x += yis same asx = x + y)-=(Subtract and assign:x -= yis same asx = x - y)*=(Multiply and assign:x *= yis same asx = x * y)/=(Divide and assign:x /= yis same asx = x / y)%=(Modulo and assign:x %= yis same asx = x % y)
// Add this to your main method
// --- Assignment Operators ---
int score = 100;
System.out.println("\n--- Assignment Operations ---");
System.out.println("Initial score: " + score);
score += 50; // score = score + 50;
System.out.println("Score after += 50: " + score); // Expected: 150
score -= 20; // score = score - 20;
System.out.println("Score after -= 20: " + score); // Expected: 130
score *= 2; // score = score * 2;
System.out.println("Score after *= 2: " + score); // Expected: 260
score /= 10; // score = score / 10;
System.out.println("Score after /= 10: " + score); // Expected: 26
2.3.3 Increment and Decrement Operators
These are special unary operators (they operate on a single operand) that add or subtract 1 from a variable. They’re very common in loops (which we’ll cover soon!).
++(Increment by 1)--(Decrement by 1)
These have two forms:
- Prefix:
++xor--x(increments/decrements then uses the value) - Postfix:
x++orx--(uses the value then increments/decrements)
// Add this to your main method
// --- Increment/Decrement Operators ---
int counter = 5;
System.out.println("\n--- Increment/Decrement Operations ---");
System.out.println("Initial counter: " + counter); // Expected: 5
counter++; // Postfix increment: uses 5, then becomes 6
System.out.println("Counter after postfix increment: " + counter); // Expected: 6
++counter; // Prefix increment: becomes 7, then uses 7
System.out.println("Counter after prefix increment: " + counter); // Expected: 7
int result1 = counter++; // result1 gets 7, then counter becomes 8
System.out.println("Result1 (postfix): " + result1 + ", Counter: " + counter); // Expected: Result1: 7, Counter: 8
int result2 = ++counter; // counter becomes 9, then result2 gets 9
System.out.println("Result2 (prefix): " + result2 + ", Counter: " + counter); // Expected: Result2: 9, Counter: 9
Explanation:
- The difference between prefix and postfix matters when the operator is part of a larger expression. If it’s just
counter++;or++counter;on its own line, the effect oncounteris the same (it increases by 1).
2.3.4 Comparison (Relational) Operators
These operators compare two values and return a boolean (either true or false). They are fundamental for making decisions in your code.
==(Equal to) - CRITICAL: This is two equals signs!!=(Not equal to)>(Greater than)<(Less than)>=(Greater than or equal to)<=(Less than or equal to)
// Add this to your main method
// --- Comparison Operators ---
int a = 10;
int b = 20;
int c = 10;
System.out.println("\n--- Comparison Operations ---");
System.out.println("a == b: " + (a == b)); // Expected: false
System.out.println("a == c: " + (a == c)); // Expected: true
System.out.println("a != b: " + (a != b)); // Expected: true
System.out.println("a > b: " + (a > b)); // Expected: false
System.out.println("a < b: " + (a < b)); // Expected: true
System.out.println("a >= c: " + (a >= c)); // Expected: true
System.out.println("b <= c: " + (b <= c)); // Expected: false
Explanation:
- Notice the parentheses around
(a == b)etc. This ensures the comparison happens before string concatenation, otherwise, you might get unexpected results or compilation errors in complex scenarios. It’s good practice. - CRITICAL PITFALL: Remember
==for comparison, not=!=is for assignment. This is a very common beginner mistake.
2.3.5 Logical Operators
These combine boolean expressions to create more complex conditions.
&&(Logical AND): Returnstrueif both operands aretrue.||(Logical OR): Returnstrueif at least one operand istrue.!(Logical NOT): Inverts the boolean value (flipstruetofalse, andfalsetotrue).
// Add this to your main method
// --- Logical Operators ---
boolean isRaining = true;
boolean hasUmbrella = false;
boolean isSunny = false;
System.out.println("\n--- Logical Operations ---");
System.out.println("isRaining && hasUmbrella: " + (isRaining && hasUmbrella)); // Expected: false (both not true)
System.out.println("isRaining || hasUmbrella: " + (isRaining || hasUmbrella)); // Expected: true (at least one is true)
System.out.println("!isSunny: " + (!isSunny)); // Expected: true (NOT false is true)
// Combining with comparison operators
int age = 25;
boolean isAdult = (age >= 18);
boolean isSenior = (age >= 65);
System.out.println("Is adult: " + isAdult); // Expected: true
System.out.println("Is adult AND not senior: " + (isAdult && !isSenior)); // Expected: true (25 is >=18 and NOT >=65)
Explanation:
- Logical operators are crucial for conditional statements (like
ifstatements, coming next chapter!) where you need to check multiple conditions simultaneously.
For a comprehensive list of Java operators and their precedence, consult the official documentation: Operators (JDK 25)
Mini-Challenge: The Simple Calculator!
Alright, time to put your new knowledge to the test!
Challenge:
Create a small Java program (you can call it Calculator.java) that performs a few basic calculations.
- Declare two
intvariables,operand1andoperand2, and assign them any whole numbers you like. - Declare a
doublevariable,taxRate, and assign it a decimal value (e.g.,0.05for 5%). - Calculate and print the
sum,difference,product, andremainderofoperand1andoperand2. Make sure the output is clear (e.g., “Sum: 15”). - Calculate the
quotientofoperand1divided byoperand2, ensuring the result is a precise decimal. Store it in adoublevariable and print it. - Imagine
operand1is a price. Calculate thefinalPriceafter applying thetaxRate. Print thisfinalPrice. - Increment
operand1by 1 using the++operator and print its new value. - Check if
operand1is now greater thanoperand2. Print thebooleanresult clearly.
Hint:
- Remember how to get precise division with
intvariables. You might need to temporarily convert one of them to adoubleduring the calculation! (This is called type casting, we’ll cover it more formally later, but for now, you can do(double)operand1 / operand2).
What to Observe/Learn:
- How to declare and initialize different data types.
- The behavior of various arithmetic operators.
- The difference between integer and floating-point division.
- How to use variables in calculations and print formatted output.
Click for Solution (but try it yourself first!)
// Calculator.java
public class Calculator {
public static void main(String[] args) {
System.out.println("--- Simple Calculator Challenge ---");
// 1. Declare two int variables
int operand1 = 25;
int operand2 = 7;
// 2. Declare a double variable for taxRate
double taxRate = 0.08; // 8% tax
System.out.println("Operand 1: " + operand1);
System.out.println("Operand 2: " + operand2);
System.out.println("Tax Rate: " + taxRate);
// 3. Calculate and print sum, difference, product, remainder
int sum = operand1 + operand2;
int difference = operand1 - operand2;
int product = operand1 * operand2;
int remainder = operand1 % operand2;
System.out.println("Sum: " + sum);
System.out.println("Difference: " + difference);
System.out.println("Product: " + product);
System.out.println("Remainder: " + remainder);
// 4. Calculate precise quotient
// We cast operand1 to a double to ensure floating-point division
double preciseQuotient = (double) operand1 / operand2;
System.out.println("Precise Quotient: " + preciseQuotient);
// 5. Calculate final price with tax
double price = operand1; // Let's use operand1 as the base price for this
double taxAmount = price * taxRate;
double finalPrice = price + taxAmount;
System.out.println("Original Price: " + price);
System.out.println("Tax Amount: " + taxAmount);
System.out.println("Final Price (with tax): " + finalPrice);
// 6. Increment operand1 and print
operand1++;
System.out.println("Operand 1 after increment: " + operand1);
// 7. Check if operand1 is greater than operand2
boolean isGreater = (operand1 > operand2);
System.out.println("Is Operand 1 greater than Operand 2 now? " + isGreater);
}
}
Common Pitfalls & Troubleshooting
Even experienced programmers make mistakes, especially with these fundamental building blocks. Here are a few common ones to watch out for:
Type Mismatch Errors:
- Mistake: Trying to assign a value of one type to a variable of an incompatible type (e.g.,
int myNum = "hello";orboolean flag = 1;). - Troubleshooting: The compiler will usually catch this with a clear error message like “incompatible types: String cannot be converted to int”. Read the error carefully! Ensure the value you’re assigning matches the declared type of the variable.
- Example:
// int wrongType = "Java"; // Compiler Error! String to int // boolean anotherWrong = 0; // Compiler Error! int to boolean
- Mistake: Trying to assign a value of one type to a variable of an incompatible type (e.g.,
Integer Division Issues:
- Mistake: Expecting a decimal result when dividing two integers.
10 / 4will be2, not2.5. - Troubleshooting: If you need a decimal result, make sure at least one of the operands is a
doubleorfloat. You can achieve this by declaring the variables asdoublefrom the start, or by casting one of them:(double)num1 / num2. - Example:
int totalItems = 10; int numPeople = 3; double itemsPerPerson = totalItems / numPeople; // This will be 3.0, not 3.33! // Correct way: double correctItemsPerPerson = (double) totalItems / numPeople; // This will be 3.33...
- Mistake: Expecting a decimal result when dividing two integers.
Confusing
=(Assignment) with==(Comparison):- Mistake: Accidentally typing
if (x = 5)instead ofif (x == 5). The first one assigns5toxand then tries to evaluate the result of the assignment as a boolean (which is usually a compile error in Java for primitives, but can lead to subtle bugs in other contexts). The second one comparesxto5. - Troubleshooting: Pay close attention when writing conditional statements. The compiler will often flag
if (x = 5)as “incompatible types: int cannot be converted to boolean” because the assignmentx = 5results in anint, not aboolean. - Example:
int myValue = 10; // if (myValue = 10) { // Compiler Error: Required type boolean, Provided int // System.out.println("Value is 10"); // } if (myValue == 10) { // Correct comparison System.out.println("Value is 10"); }
- Mistake: Accidentally typing
Summary
Phew! You’ve covered a lot of ground in this chapter. Let’s quickly recap the key takeaways:
- Variables are named containers in memory used to store data.
- You must declare a variable with a specific data type and initialize it with a value before using it.
- Use
finalto declare constants, values that cannot change after initialization (conventionallyALL_CAPS). - Java has primitive data types for basic values (
int,double,boolean,char, etc.) and reference data types for objects (Stringbeing our first example). - Operators allow you to perform actions on variables and values:
- Arithmetic:
+,-,*,/,% - Assignment:
=,+=,-=, etc. - Increment/Decrement:
++,--(watch out for prefix vs. postfix in expressions!) - Comparison:
==,!=,>,<,>=,<=(returnbooleanvalues) - Logical:
&&,||,!(combinebooleanexpressions)
- Arithmetic:
- Be mindful of integer division and the crucial difference between
=(assignment) and==(comparison).
You’re building a strong foundation! With variables, data types, and operators, you can now store information, perform calculations, and prepare to make decisions in your programs.
In the next chapter, we’ll take these building blocks and learn how to make your programs make decisions and repeat actions using control flow statements like if/else and loops. Get ready to add some real intelligence to your Java applications!