Java Fundamentals: A Complete Guide to Data Types, Variables, and Operators
Hey there! π Welcome to the first post in my Java Fundamentals series!
I'm revisiting Java to refresh my memory and fill in some gaps in my knowledge. If you're also coming from other programming languages or just need a comprehensive review of Java's core concepts, this guide is for you.
"Java was designed to be easy to use and is therefore easier to write, compile, debug, and learn than other programming languages." β James Gosling, Creator of Java
Java is a statically typed language with explicit type declarations that help catch errors at compile time.
Let's dive into the fundamentals! π
Data Types in Java
Java data types are divided into two main categories: primitive and non-primitive (reference) types.
Primitive Data Types
Java provides eight primitive data types, each with specific memory allocation and use cases:
Numeric Data Types
Integer Types:
-
byte
- 8 bits (range: -128 to 127)- Example:
byte count = 100;
- Example:
-
short
- 16 bits (range: -32,768 to 32,767)- Example:
short population = 30000;
- Example:
-
int
- 32 bits (range: -2Β³ΒΉ to 2Β³ΒΉ-1)- Example:
int salary = 100000;
- Most commonly used integer type in Java
- Example:
-
long
- 64 bits (range: -2βΆΒ³ to 2βΆΒ³-1)- Example:
long distance = 1000000000L;
- Double precision (about 15-16 decimal digits)
- Must use suffix 'L' or 'l' to indicate long type
- Example:
Floating-Point Types:
-
float
- 32 bits (IEEE 754 single precision)- Example:
float pi = 3.14f;
- Single precision (about 6-7 decimal digits)
- Must use suffix 'f' or 'F' to indicate float type
- β οΈ Note: If a long is assigned to float, it will be implicitly converted with potential data loss
- Example:
-
double
- 64 bits (IEEE 754 double precision)- Example:
double precise = 3.1415926535;
- Default floating-point type in Java (no suffix needed)
- Double precision (about 15-16 decimal digits)
- Example:
Character and Boolean Types
-
char
- 16 bits (Unicode UTF-16)- Example:
char grade = 'A';
- β οΈ Important: Uses Unicode UTF-16, do not assume ASCII encoding
- Example:
-
boolean
- Conceptually 1 bit (JVM dependent)- Example:
boolean isActive = true;
- Can only hold
true
orfalse
values - Actual memory usage is JVM-dependent (can be 1 bit, 8 bits, or 32 bits)
- Example:
Non-Primitive (Reference) Data Types
Reference types are stored as references/pointers in memory and have a default value of null
:
- String - Sequence of characters
- Arrays - Collection of elements of the same type
- Classes - User-defined types
- Interfaces - Contracts for class implementation
- Enums - Fixed set of constants
- Records - Immutable data carriers (added in Java 14)
Default Value Behavior
Default values are automatically applied to instance variables and static variables, but not to local variables. In other words, all class-level variables receive default values automatically.
public class Test {
static int x; // default: 0 (static variable)
int y; // default: 0 (instance variable)
public static void main(String[] args) {
int z; // must be initialized explicitly (local variable)
// System.out.println(z); // Compile-time error: variable not initialized
}
}
Type Casting in Java
Java supports two types of casting:
Implicit Casting (Widening Conversion)
Automatic conversion from smaller to larger data types occurs without data loss:
byte b = 10;
int i = b; // Implicit widening - no casting required
double d = i; // Implicit widening - no casting required
Widening Conversion Order:
byte β short β int β long β float β double
Explicit Casting (Narrowing Conversion)
Manual conversion from larger to smaller data types may result in data loss:
int i = 300;
byte b = (byte) i; // β οΈ Explicit casting required - overflow occurs
System.out.println(b); // Output: 44 (data loss due to overflow)
double d = 9.99;
int j = (int) d; // β οΈ Explicit casting required - decimal part lost
System.out.println(j); // Output: 9
Special Casting Cases
Numeric Promotion: byte
, short
, and char
are automatically promoted to int
during arithmetic operations:
byte b1 = 10;
byte b2 = 20;
int sum = b1 + b2; // Automatically promoted to int
System.out.println(sum); // Output: 30
Variables in Java
Types of Variables
1. Local Variables
- Scope: Declared inside methods, blocks, or constructors
- Memory: Stored in the stack
- Lifetime: Exist until method/block/constructor execution completes
- Initialization: Must be explicitly initialized before use
void method() {
int localVar;
// System.out.println(localVar); // β Compile error: variable not initialized
localVar = 10; // β
Now it can be used
System.out.println(localVar); // Output: 10
}
Variable Shadowing: When a local variable has the same name as an instance variable, it shadows the instance variable within its scope:
class Test {
int x = 10; // instance variable
void method() {
int x = 20; // local variable shadows instance variable
System.out.println(x); // Output: 20 (local variable)
System.out.println(this.x); // Output: 10 (instance variable)
}
}
2. Instance Variables
- Scope: Declared inside a class but outside methods
- Memory: Stored in the heap
- Lifetime: Exist as long as the object exists
- Copies: Each object has its own copy
- Initialization: Automatically assigned default values
class Car {
String color; // default: null
int speed; // default: 0
boolean isNew; // default: false
}
3. Static Variables (Class Variables)
- Scope: Declared with the
static
keyword - Memory: Stored in the method area of heap
- Lifetime: Exist for the entire program execution
- Sharing: Shared across all instances of the class
- Ownership: Belong to the class, not to individual instances
class Car {
static int wheels = 4; // shared by all Car objects
String model; // unique to each Car object
}
// Usage
Car car1 = new Car();
Car car2 = new Car();
System.out.println(Car.wheels); // Output: 4 (accessed via class name)
Variable Naming Conventions
π§ Best Practice: Use camelCase for variable names (e.g.,
myVariable
) and PascalCase for class names (e.g.,MyClass
).
Follow these rules when naming variables in Java:
- β
Must start with a letter, underscore (
_
), or dollar sign ($
) - β Can contain letters, digits, underscores, or dollar signs
- β Cannot start with a digit
- β Cannot use reserved keywords (
int
,class
,public
, etc.) - β οΈ Case-sensitive (
myVar
andmyvar
are different variables)
Examples:
// β
Valid variable names
int age;
String _name;
double $price;
boolean isValid2;
// β Invalid variable names
// int 2count; // starts with digit
// String class; // reserved keyword
// boolean my-var; // contains hyphen
Operators in Java
Operators are special symbols that perform operations on operands (variables and values).
Operator Categories
Category | Purpose | Examples |
---|---|---|
Arithmetic Operators | Perform mathematical operations | + , - , * , / , % |
Relational Operators | Compare two values | == , != , > , < , >= , <= |
Logical Operators | Combine multiple boolean expressions | && , || , ! |
Bitwise Operators | Operate on individual bits | & , | , ^ , ~ , << , >> , >>> |
Assignment Operators | Assign values to variables | = , += , -= , *= , /= , %= |
Unary Operators | Operate on a single operand | ++ , -- , + , - , ! |
Ternary Operator | Shorthand conditional operator | ? : |
instanceof | Check object type at runtime | obj instanceof ClassName |
Practical Examples
Arithmetic Operators:
int a = 10, b = 3;
System.out.println(a + b); // Addition: 13
System.out.println(a - b); // Subtraction: 7
System.out.println(a * b); // Multiplication: 30
System.out.println(a / b); // Division: 3 (integer division)
System.out.println(a % b); // Modulus: 1 (remainder)
Logical Operators:
boolean x = true, y = false;
System.out.println(x && y); // Logical AND: false
System.out.println(x || y); // Logical OR: true
System.out.println(!x); // Logical NOT: false
Ternary Operator:
int age = 18;
String status = (age >= 18) ? "Adult" : "Minor";
System.out.println(status); // Output: "Adult"
Operator Precedence
Precedence Level | Operator Type | Operators |
---|---|---|
Highest | Parentheses | () |
1 | Unary | ++ , -- , + , - , ! , ~ |
2 | Multiplicative | * , / , % |
3 | Additive | + , - |
4 | Shift | << , >> , >>> |
5 | Relational | < , <= , > , >= , instanceof |
6 | Equality | == , != |
7 | Bitwise AND | & |
8 | Bitwise XOR | ^ |
9 | Bitwise OR | ` |
10 | Logical AND | && |
11 | Logical OR | ` |
12 | Ternary | ? : |
Lowest | Assignment | = , += , -= , *= , /= , %= |
Precedence in Action
int result = 10 + 5 * 2; // Multiplication first: 10 + (5 * 2) = 20
int result2 = (10 + 5) * 2; // Parentheses first: (10 + 5) * 2 = 30
Best Practices and Tips
- Always initialize local variables before using them
- Use meaningful variable names that describe their purpose
- Be aware of data type ranges to prevent overflow
- Use parentheses to make operator precedence explicit
- Consider memory optimization when choosing between similar data types
- Understand the difference between
=
(assignment) and==
(comparison)
Conclusion
Happy coding! π»