Java Core Fundamentals: Data Types and Operators
Variables
Variables are named memory storage units that hold mutable values during program runtime. You can define variables using two standard patterns:
- Separate declaration and assignment: First specify the data type followed by the variable name, then assign a value to the variable in a separate line.
- Combined declaration and initialization: Assign a value to the variable immediately when declaring it.
Key constraints for local variables (variables defined inside method scopes):
- Local variables must be initialized before use, otherwise the compiler will throw an "uninitialized variable" error.
- Duplicate variable names are not allowed within the same method scope.
- Declaring a variable essentially requests a memory block matching its data type from the operating system.
public class MultiVarDeclareDemo {
public static void main(String[] args) {
// Declare multiple integer variables in a single line
int x, y, k;
x = 15;
y = 25;
k = 35;
System.out.println(x);
System.out.println(y);
System.out.println(k);
// Declare and initialize multiple variables in one line
int x1 = 65, y1 = 75, k1 = 95;
System.out.println(x1);
System.out.println(y1);
System.out.println(k1);
}
}
public class SingleVarDemo {
public static void main(String[] args) {
int count;
count = 35;
System.out.println(count);
// Duplicate declaration will throw compile error: int count = 4.25;
}
}
Integer Data Types
Java provides four signed integer types with different storage sizes and value ranges:
| Type | Storage Size (bytes) | Bit Length | Value Range |
|---|---|---|---|
| byte | 1 | 8 | [-128, 127] |
| short | 2 | 16 | [-32768, 32767] |
| int | 4 | 32 | Default integer type, range [-2^31, 2^31 -1] |
| long | 8 | 64 | [-2^63, 2^63 -1] |
Important notes:
- All integer literals are treated as int type by default.
- To define a long type literal, append
L(recommended, avoid lowercaselwhich is easily confused with the digit 1) to the end of the value.
Integer storage basics: Each binary digit (0 or 1) occupies 1 bit, 1 byte = 8 bits. The highest bit of a signed integer is the sign bit: 0 for positive numbers, 1 for negative numbers. Positive integers use identical values for original code, inverse code and complement code. For negative integers, complement code is used for storage, calculated as inverse code (sign bit remains unchanged, other bits flipped) plus 1.
public class IntegerTypeDemo {
public static void main(String[] args) {
/*
30 in binary: 0001 1110
-30 original code: 1001 1110
-30 inverse code: 1110 0001
-30 complement code: 1110 0010
*/
byte age = 18;
short orderId = 2100;
int userCount = 35000;
long totalVisit = 42000L;
// Use underscores to separate digits for improved readability
long largeNum = 31_0000_0000L;
System.out.println("largeNum = " + largeNum);
System.out.println("age = " + age);
System.out.println("orderId = " + orderId);
System.out.println("userCount = " + userCount);
System.out.println("totalVisit = " + totalVisit);
System.out.println(77_7777_7777L);
}
}
Floating Point Types
Java supports two floating point types for storing fractional values:
- float: 4 bytes storage, single precision
- double: 8 bytes storage, double precision, default floating point type
Key notes:
- All floating point literals are treated as double by default. To define a float literal, append
Forfto the end of the value. - Floating point types store approximate values rather than exact decimals. For precise decimal calculation scenarios (e.g. financial accounting), use the
java.math.BigDecimalclass. - Floating point values are stored in a structured format consisting of sign bit, exponent bit and mantissa bit.
public class FloatTypeDemo {
public static void main(String[] args) {
float price = 4.99f;
price = 7.89F;
System.out.println("price = " + price);
double distance = 8.45E4;
System.out.println("distance = " + distance);
double longDecimal = 9.999999999999999999;
System.out.println("longDecimal = " + longDecimal);
// Floating point precision limitation
System.out.println(0.1 + 0.2); // Expected 0.3, actual output 0.30000000000000004
}
}
char Character Type
char is a 2-byte unsigned type used to store a single Unicode character. Common ASCII value references:
- Uppercase 'A' corresponds to 65
- Lowercase 'a' corresponds to 97
- Digit '0' corresponds to 48
Common escape sequences:
| Escape Sequence | Function |
|---|---|
| \n | Line break |
| \t | Tab character |
| " | Double quote inside string |
| \ | Backslash inside string |
| \b | Backspace |
| \r | Carriage return (move cursor to start of current line) |
Primitive Type Conversion
Java primitive types support implicit and explicit conversion, ordered by storage capacity from smallest to largest:
byte < short/char < int < long < float < double
Implicit type promotion:
- Assigning a value of a smaller capacity type to a larger capacity type happens automatically without explicit declaration.
- When multiple types participate in an operation, the result is automatically promoted to the type with the largest capacity in the operation.
Explicit type casting:
Used when assigning a larger capacity type value to a smaller capacity type. Syntax:
TargetType variableName = (TargetType) sourceValue;
Important conversion rules:
- Casting a floating point number to integer will discard all decimal parts directly, no rounding occurs.
- Casting a large integer to a smaller type will only retain the lower bits matching the target type, which may cause unexpected value overflow.
- When byte, short or char types participate in arithmetic operations, they are automatically promoted to int first, so the result of their addition is always int type.
public class TypeConvertDemo1 {
public static void main(String[] args) {
long total = 15 + 25L + 30 + 7;
double sum = 15 + 25L + 4.25F + 7.85;
byte num1 = 12;
int num2 = num1;
System.out.println("num2 = " + num2);
int count = 456;
float floatCount = count;
System.out.println("floatCount = " + floatCount);
}
}
public class TypeConvertDemo2 {
public static void main(String[] args) {
float rate = (float) 4.12;
System.out.println("rate = " + rate);
double score = 8.7;
int intScore = (int) score;
System.out.println("intScore = " + intScore);
int code = 66;
char charCode = (char) code;
System.out.println("charCode = " + charCode);
int bigNum = 220;
/*
Binary of 220: 0000 0000 0000 0000 0000 0000 1101 1100
When cast to byte, only keep lower 8 bits: 1101 1100 (complement)
Inverse code: 1101 1011, original code: 1010 0100 = -36
*/
byte smallNum = (byte) bigNum;
System.out.println("smallNum = " + smallNum);
}
}
public class TypeConvertDemo3 {
public static void main(String[] args) {
byte val1 = 15 + 15;
short val2 = 30 + 30;
System.out.println("val1 = " + val1 + ", val2 = " + val2);
char ch = 'B' + val2;
System.out.println(ch);
String greeting = "Hi";
int a = 15;
int b = 25;
System.out.println(greeting + a + b);
System.out.println("Jack" + false);
}
}
Arithmetic Operators
Common arithmetic operators in Java:
+: Can be used as positive sign, addition operator, or string concatenation operator when one operand is a string.-: Can be used as negative sign, or subtraction operator.*: Multiplication operator./: Division operator. Integer division truncates decimal parts directly, no rounding occurs.%: Modulo operator, returns the remainder of division. A remainder of 0 indicates exact division.++: Increment operator.++varincrements the variable by 1 first, then uses the new value for operation.var++uses the original value for operation first, then increments the variable by 1.--: Decrement operator, follows the same prefix/suffix execution rule as the increment operator.