In Java, variables are used to store data values. Before using a variable, you must declare it by specifying its type and name. You can also initialize the variable by assigning it a value. Declaration and initialization can be done separately or combined.
A variable declaration tells the compiler about the variable's type and name:
int age; // Declares an integer variable named age
double price; // Declares a double variable named price
String name; // Declares a String variable named name
At this point, the variables exist but do not hold any meaningful value (they have default values if they are instance or class variables, but local variables must be initialized before use).
You assign a value to a variable using the assignment operator =
:
age = 25; // Initializes age with 25
price = 19.99; // Initializes price with 19.99
name = "Alice"; // Initializes name with the string "Alice"
It is common and often clearer to declare and initialize a variable in a single statement:
int age = 25;
double price = 19.99;
String name = "Alice";
This approach reduces errors and makes your code easier to read.
You can declare multiple variables of the same type on one line, though it is best to initialize them separately for clarity:
int x = 10, y = 20, z = 30; // Multiple variables declared and initialized
count
, totalPrice
, or userName
.a
, temp
), unless in very limited contexts.
public class VariableDemo {
public static void main(String[] args) {
// Declaration
int age;
double price;
String name;
// Initialization
age = 25;
price = 19.99;
name = "Alice";
// Combined declaration and initialization
int score = 100;
double taxRate = 0.13;
String city = "Toronto";
// Multiple variable declarations (same type)
int x = 10, y = 20, z = 30;
// Output values
System.out.println("Age: " + age);
System.out.println("Price: $" + price);
System.out.println("Name: " + name);
System.out.println("Score: " + score);
System.out.println("Tax Rate: " + taxRate);
System.out.println("City: " + city);
System.out.println("x: " + x + ", y: " + y + ", z: " + z);
}
}
Clear and consistent variable declaration and initialization make your code easier to understand and maintain. Combining declaration and initialization is a good habit that prevents uninitialized variable errors. Choosing descriptive variable names following conventions improves readability and helps others (and your future self) grasp the code's intent quickly. Mastering variables is a fundamental step toward effective Java programming.
Java provides eight primitive data types that store simple values directly in memory. These types are the building blocks for storing data efficiently and performing fast operations.
Type | Size (bits) | Description | Example Declaration |
---|---|---|---|
byte |
8 | Small integer, from -128 to 127 | byte b = 100; |
short |
16 | Larger integer, from -32,768 to 32,767 | short s = 30000; |
int |
32 | Standard integer, from -2³¹ to 2³¹-1 | int i = 1_000_000; |
long |
64 | Large integer, from -2⁶³ to 2⁶³-1 | long l = 10_000_000_000L; |
float |
32 | Single-precision floating point | float f = 3.14f; |
double |
64 | Double-precision floating point | double d = 3.14159; |
char |
16 | A single Unicode character | char c = 'A'; |
boolean |
1 (logical) | True or false value | boolean flag = true; |
int
for most whole number calculations because it balances memory and performance well.long
when values exceed the int
range (e.g., large counters or timestamps). Remember to append L
to literals.byte
and short
mainly when memory is a concern, such as large arrays, but be cautious about implicit conversions.float
and double
for decimal numbers. Prefer double
for higher precision; float
is mostly used in graphics or when memory is limited.char
to store single characters, such as letters or digits. Note that it stores Unicode characters.boolean
for true/false logic conditions.int age = 30;
double price = 19.99;
char grade = 'A';
boolean isActive = false;
byte smallNumber = 100;
long population = 7_800_000_000L;
float piApprox = 3.14f;
short temperature = -10;
Choosing the right primitive type affects memory usage and performance. Smaller types save memory but may require extra care when performing operations or conversions. Larger types like long
and double
use more space but allow a wider range or precision. Understanding these types helps you write efficient Java code tailored to your program's needs.
In Java, type conversion happens when you assign a value from one data type to another. This can be implicit (automatic) or explicit (manual casting). Understanding these conversions is essential to avoid data loss and runtime errors.
Java automatically converts smaller numeric types to larger ones because there is no risk of losing information. This is called widening conversion.
Example:
int i = 100;
long l = i; // int implicitly cast to long
float f = l; // long implicitly cast to float
Here, int
converts to long
, and then long
converts to float
without explicit code because the target type can hold all possible values of the source type.
When converting from a larger type to a smaller one, you must explicitly cast the value. This is called narrowing conversion and may cause data loss.
Example:
double d = 9.78;
int i = (int) d; // explicit cast from double to int, fractional part lost
System.out.println(i); // Output: 9
Casting a double
to an int
truncates the decimal part, which can cause loss of precision.
Another example with possible overflow:
int big = 130;
byte b = (byte) big; // byte range is -128 to 127
System.out.println(b); // Output: -126 (due to overflow)
Because 130
exceeds the byte range, the value wraps around, leading to unexpected results.
public class TypeCastingDemo {
public static void main(String[] args) {
// ===== Implicit Casting (Widening Conversion) =====
int i = 100;
long l = i; // int -> long
float f = l; // long -> float
System.out.println("=== Implicit Casting ===");
System.out.println("int value: " + i);
System.out.println("long value (from int): " + l);
System.out.println("float value (from long): " + f);
// ===== Explicit Casting (Narrowing Conversion) =====
double d = 9.78;
int i2 = (int) d; // double -> int (fractional part lost)
int big = 130;
byte b = (byte) big; // int -> byte (overflow expected)
System.out.println("\n=== Explicit Casting ===");
System.out.println("double value: " + d);
System.out.println("int value (from double): " + i2);
System.out.println("int value (for overflow): " + big);
System.out.println("byte value (from int): " + b);
}
}
Casting allows flexibility in operations involving different numeric types and helps the compiler understand how to handle assignments. Without casting, certain assignments would cause compilation errors.
Casting is a powerful tool but must be used carefully. Always be aware of the types involved and the possible effects of narrowing conversions. When precision and data integrity are critical, avoid unnecessary casts and prefer using types that can safely hold your values. Understanding type conversion helps you write robust and predictable Java programs.
final
In Java, the final
keyword is used to declare constants—variables whose values cannot be changed once assigned. Using constants improves code readability and helps prevent accidental modification of important values.
To declare a constant, use final
before the variable type. By convention, constant names are written in uppercase letters with underscores separating words:
final int MAX_USERS = 100;
final double PI = 3.14159;
final String APP_NAME = "JavaSyntaxBook";
Once a final
variable is initialized, attempting to change its value causes a compile-time error:
MAX_USERS = 200; // Error: cannot assign a value to final variable MAX_USERS
This restriction ensures that constants remain fixed throughout the program.
Using final
constants makes your code easier to read and maintain by clearly indicating values that are meant to stay the same. Constants serve as single sources of truth, preventing "magic numbers" or hard-coded values scattered throughout your code. This is especially useful for configuration settings, limits, or fixed parameters like mathematical constants. Declaring constants also helps prevent bugs caused by unintended variable reassignment, increasing the robustness of your programs.
var
)Starting from Java 10, you can declare local variables using the var
keyword, which allows the compiler to infer the variable's type based on the assigned value. This feature reduces verbosity while maintaining type safety.
Instead of explicitly specifying the type, you write:
var message = "Hello, world!"; // inferred as String
var count = 100; // inferred as int
var list = new ArrayList<String>(); // inferred as ArrayList<String>
The compiler determines the type at compile time, so var
does not make Java dynamically typed; the variable still has a fixed type.
var x; // Error: cannot use 'var' without initialization
null
without type: Because null
alone doesn't provide type information, you cannot do this:var obj = null; // Error: cannot infer type from null
var
cannot be used for method parameters, fields, or return types.var
Improves Clarityvar map = new HashMap<String, List<Integer>>();
var
Reduces Readabilityvar
with unclear or complex expressions may make it harder to understand the variable's type at a glance.var result = processData(); // What is the type of result?
var
helps write cleaner, less cluttered code, especially with long type names. However, use it thoughtfully—clear, explicit types can sometimes improve readability, especially for beginners or complex codebases. Balancing var
usage with clarity ensures maintainable and understandable Java programs.
import java.util.*;
public class VarExample {
public static void main(String[] args) {
// ===== Correct Syntax: Type Inference with 'var' =====
var message = "Hello, world!"; // inferred as String
var count = 100; // inferred as int
var list = new ArrayList<String>(); // inferred as ArrayList<String>
var map = new HashMap<String, List<Integer>>(); // inferred as HashMap<String, List<Integer>>
System.out.println("Message: " + message);
System.out.println("Count: " + count);
list.add("Java");
System.out.println("List: " + list);
map.put("scores", List.of(85, 90, 95));
System.out.println("Map: " + map);
// ===== Limitation Examples (Commented Out) =====
// var x; // ❌ Error: cannot use 'var' without initializer
// var obj = null; // ❌ Error: cannot infer type from null
// ===== Readability Considerations =====
var name = "Alice"; // clear and obvious
var total = calculateTotal(5, 3); // not clear what type 'total' is at a glance
System.out.println("Name: " + name);
System.out.println("Total: " + total);
}
static double calculateTotal(int a, int b) {
return a * b * 1.5;
}
}
In Java, literals are fixed values directly written in code. They represent data like numbers, characters, or boolean values. Understanding literal syntax helps write clear and readable code.
int decimal = 1234;
0b
or 0B
:int binary = 0b1010; // equals decimal 10
0x
or 0X
:int hex = 0xFF; // equals decimal 255
int largeNumber = 1_000_000;
double
:double pi = 3.14159;
f
or F
suffix for float
literals:float gravity = 9.8f;
double avogadro = 6.022e23;
' '
to represent a single Unicode character:char letter = 'A';
char digit = '7';
char smiley = '\u263A';
true
and false
:boolean isJavaFun = true;
boolean isFishTasty = false;
public class LiteralsDemo {
public static void main(String[] args) {
// ===== Integer Literals =====
int decimal = 1234;
int binary = 0b1010; // 10 in decimal
int hex = 0xFF; // 255 in decimal
int largeNumber = 1_000_000;
// ===== Floating-Point Literals =====
double pi = 3.14159;
float gravity = 9.8f;
double avogadro = 6.022e23;
// ===== Character Literals =====
char letter = 'A';
char digit = '7';
char smiley = '\u263A'; // ☺
// ===== Boolean Literals =====
boolean isJavaFun = true;
boolean isFishTasty = false;
// ===== Output =====
System.out.println("=== Integer Literals ===");
System.out.println("Decimal: " + decimal);
System.out.println("Binary (0b1010): " + binary);
System.out.println("Hexadecimal (0xFF): " + hex);
System.out.println("Large Number (with underscores): " + largeNumber);
System.out.println("\n=== Floating-Point Literals ===");
System.out.println("Double (pi): " + pi);
System.out.println("Float (gravity): " + gravity);
System.out.println("Scientific Notation (Avogadro's number): " + avogadro);
System.out.println("\n=== Character Literals ===");
System.out.println("Letter: " + letter);
System.out.println("Digit: " + digit);
System.out.println("Smiley (Unicode): " + smiley);
System.out.println("\n=== Boolean Literals ===");
System.out.println("Is Java fun? " + isJavaFun);
System.out.println("Is fish tasty? " + isFishTasty);
}
}
Using the appropriate literal format increases code clarity and reduces errors. Underscores help make large numbers easier to read. Choosing the right literal suffix (f
for floats, 0x
for hex) avoids confusion and unintended data type issues. Clear, consistent literal usage is a simple but important part of writing clean Java syntax.
In Java, escape sequences are special characters used inside string and character literals to represent otherwise hard-to-type or invisible characters. They begin with a backslash \
.
Escape Sequence | Description | Example Output |
---|---|---|
\n |
New line | Moves to the next line |
\t |
Tab | Inserts a horizontal tab |
\\ |
Backslash | Prints a single backslash \ |
\" |
Double quote | Prints a double quote " |
\' |
Single quote | Prints a single quote ' |
\r |
Carriage return | Returns cursor to line start |
\b |
Backspace | Deletes the previous character |
System.out.println("Hello\nWorld!"); // Prints on two lines
System.out.println("Column1\tColumn2"); // Tab space between words
System.out.println("C:\\Program Files"); // Prints C:\Program Files
System.out.println("She said, \"Java is fun!\""); // Prints quotes inside string
Output:
Hello
World!
Column1 Column2
C:\Program Files
She said, "Java is fun!"
Escape sequences are essential for formatting output and including special characters inside strings. A common mistake is forgetting to escape backslashes or quotes, which leads to syntax errors or incorrect output. Using escape sequences properly allows you to produce readable and well-structured console output and handle string data that contains special characters without breaking the code. Mastery of escape sequences improves your ability to manipulate text in Java programs efficiently.