Operators (Java)
Operators are symbols used to calculate, compare, and evaluate variables and values. Java has many types of operators, but mastering arithmetic, comparison, and logical operators covers the vast majority of everyday code. This page also explains the truncation behavior of integer division, the special nature of + for string concatenation, and how short-circuit evaluation works.
Arithmetic Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Addition (also used for string concatenation) | cursedEnergy + 100 | value of cursedEnergy + 100 |
- | Subtraction | hp - damage | value of hp − value of damage |
* | Multiplication | power * 2 | value of power × 2 |
/ | Division (integer ÷ integer truncates the decimal) | 7 / 2 | 3 (decimal truncated) |
% | Modulus (remainder of division) | 7 % 2 | 1 |
++ | Increment (add 1) | level++ | adds 1 to level |
-- | Decrement (subtract 1) | level-- | subtracts 1 from level |
Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
== | Equal to (compares values for primitives; compares references for objects) | grade == 1 |
!= | Not equal to | status != "cursed spirit" |
> | Greater than | cursedEnergy > 9000 |
>= | Greater than or equal to | cursedEnergy >= 9000 |
< | Less than | hp < 0 |
<= | Less than or equal to | hp <= 0 |
Logical Operators and Short-Circuit Evaluation
| Operator | Meaning | Description |
|---|---|---|
&& | Logical AND | If the left operand is false, the right operand is not evaluated (short-circuit). Returns true only when both are true. |
|| | Logical OR | If the left operand is true, the right operand is not evaluated (short-circuit). Returns true when either is true. |
! | Logical NOT | Flips true to false and false to true. |
Short-circuit evaluation means that when the result of the whole expression is determined by the left operand alone, the right operand is not evaluated. With &&, if the left side is false, the result is already false, so the right side is skipped. With ||, if the left side is true, the result is already true, so the right side is skipped. This is useful for placing a null check before a method call, for example.
Sample Code
ArithmeticDemo.java
public class ArithmeticDemo {
public static void main(String[] args) {
// --- Basic arithmetic operators ---
int cursedEnergy = 300000; // Itadori Yuji's cursed energy level.
int boost = 50000; // Boost amount from Black Flash.
System.out.println("Addition: " + (cursedEnergy + boost)); // 350000
System.out.println("Subtraction: " + (cursedEnergy - boost)); // 250000
System.out.println("Multiplication: " + (cursedEnergy * 2)); // 600000
System.out.println("Division: " + (cursedEnergy / boost)); // 6 (decimal truncated)
System.out.println("Modulus: " + (cursedEnergy % boost)); // 0
// --- Notes on integer division ---
// Dividing two ints truncates the decimal portion.
int totalFloors = 10;
int clearedFloors = 3;
int intResult = totalFloors / clearedFloors; // 3 (decimal truncated)
// Casting to double before dividing gives an accurate decimal result.
double doubleResult = (double) totalFloors / clearedFloors; // 3.3333...
System.out.println("int division (truncated): " + intResult); // 3
System.out.println("double division (accurate): " + doubleResult); // 3.3333333333333335
// --- Increment and decrement ---
int grade = 1; // Year level.
grade++; // Add 1 (grade = 2).
System.out.println("After advancing a year: " + grade); // 2
grade--; // Subtract 1 (grade = 1).
System.out.println("After repeating a year: " + grade); // 1
// --- Difference between prefix and postfix ---
// Postfix (grade++): uses the current value, then increments.
// Prefix (++grade): increments first, then uses the value.
int kills = 5;
System.out.println("Postfix: " + kills++); // 5 (prints, then adds)
System.out.println("After adding: " + kills); // 6
int kills2 = 5;
System.out.println("Prefix: " + ++kills2); // 6 (adds, then prints)
System.out.println("After adding: " + kills2); // 6
}
}
javac ArithmeticDemo.java java ArithmeticDemo Addition: 350000 Subtraction: 250000 Multiplication: 600000 Division: 6 Modulus: 0 int division (truncated): 3 double division (accurate): 3.3333333333333335 After advancing a year: 2 After repeating a year: 1 Postfix: 5 After adding: 6 Prefix: 6 After adding: 6
StringConcatDemo.java
public class StringConcatDemo {
public static void main(String[] args) {
// --- Using + for string concatenation ---
// Using + with a String produces string concatenation.
String name = "五条悟";
String title = "Special Grade Sorcerer";
String result = name + " (" + title + ")";
System.out.println(result); // 五条悟 (Special Grade Sorcerer)
// --- Mixing numbers and strings with + produces string concatenation ---
// Expressions are evaluated left to right, so the order matters.
int grade = 2;
int sectionNum = 5;
// The first operand is a String, so the whole expression becomes string concatenation.
System.out.println("Year: " + grade + " Section: " + sectionNum); // Year: 2 Section: 5
// Parentheses force numeric addition before concatenation.
System.out.println("Total: " + (grade + sectionNum)); // Total: 7
// Without parentheses, number + number + string: addition happens first.
System.out.println(grade + sectionNum + " chapters"); // 7 chapters (numeric addition)
// If a string comes first, everything is concatenated.
System.out.println("Chapter: " + grade + sectionNum); // Chapter: 25 (concatenation)
}
}
javac StringConcatDemo.java java StringConcatDemo 五条悟 (Special Grade Sorcerer) Year: 2 Section: 5 Total: 7 7 chapters Chapter: 25
ComparisonLogicalDemo.java
public class ComparisonLogicalDemo {
public static void main(String[] args) {
// Jujutsu Kaisen sorcerer data.
String sorcererName = "乙骨憂太";
int cursedEnergy = 500000;
boolean isSpecialGrade = true;
// --- Comparison operators ---
System.out.println("cursedEnergy == 500000 : " + (cursedEnergy == 500000)); // true
System.out.println("cursedEnergy != 300000 : " + (cursedEnergy != 300000)); // true
System.out.println("cursedEnergy >= 500000: " + (cursedEnergy >= 500000)); // true
System.out.println("cursedEnergy < 100000: " + (cursedEnergy < 100000)); // false
// --- Logical operators ---
// &&(AND): true only when both are true.
boolean isElite = cursedEnergy >= 400000 && isSpecialGrade;
System.out.println("Is elite sorcerer: " + isElite); // true
// ||(OR): true when at least one is true.
boolean isDanger = cursedEnergy >= 400000 || sorcererName.equals("五条悟");
System.out.println("Is danger level: " + isDanger); // true
// !(NOT): flips true/false.
boolean isNotSpecial = !isSpecialGrade;
System.out.println("Is not special grade: " + isNotSpecial); // false
// --- Short-circuit evaluation ---
// && skips the right side if the left side is false.
// Placing a null check before a method call prevents NullPointerException.
String domain = null; // Domain expansion name (not yet expanded, so null).
// Calling domain.length() when domain is null would throw a NullPointerException.
// Short-circuit evaluation of && means the right side (domain.length() > 0) is not evaluated when the left is false.
if (domain != null && domain.length() > 0) {
System.out.println("Domain name: " + domain);
} else {
System.out.println("Domain is not expanded."); // This branch runs.
}
// Example of || short-circuit evaluation.
// Once the left side is true, the right side is not evaluated.
boolean hasWeapon = true;
boolean hasCursedTool = false;
// Since hasWeapon is true, evaluation of hasCursedTool is skipped.
if (hasWeapon || hasCursedTool) {
System.out.println(sorcererName + " is armed."); // This branch runs.
}
}
}
javac ComparisonLogicalDemo.java java ComparisonLogicalDemo cursedEnergy == 500000 : true cursedEnergy != 300000 : true cursedEnergy >= 500000: true cursedEnergy < 100000: false Is elite sorcerer: true Is danger level: true Is not special grade: false Domain is not expanded. 乙骨憂太 is armed.
Assignment Operators and Ternary Operator
| Operator | Meaning | Example | Equivalent |
|---|---|---|---|
+= | Add and assign | hp += 100 | hp = hp + 100 |
-= | Subtract and assign | hp -= 50 | hp = hp - 50 |
*= | Multiply and assign | power *= 2 | power = power * 2 |
/= | Divide and assign | energy /= 3 | energy = energy / 3 |
%= | Modulus and assign | energy %= 100 | energy = energy % 100 |
condition ? A : B | Ternary operator: A if condition is true, B if false | grade >= 90 ? "Special" : "General" | — |
AssignTernaryDemo.java
public class AssignTernaryDemo {
public static void main(String[] args) {
// --- Assignment operators ---
int cursedEnergy = 300000; // Itadori Yuji's initial cursed energy.
cursedEnergy += 50000; // Boost after Black Flash (+= adds and assigns).
System.out.println("After Black Flash: " + cursedEnergy); // 350000
cursedEnergy -= 80000; // Depleted in battle (-= subtracts and assigns).
System.out.println("After depletion: " + cursedEnergy); // 270000
cursedEnergy *= 2; // Doubled during domain expansion (*= multiplies and assigns).
System.out.println("After domain expansion: " + cursedEnergy); // 540000
int remainder = cursedEnergy;
remainder %= 100000; // Remainder in units of 100,000 (%= applies modulus and assigns).
System.out.println("Remainder: " + remainder); // 40000
// --- Ternary operator ---
// condition ? value if true : value if false
int level = 85;
String grade = (level >= 90) ? "Special Grade" : (level >= 70) ? "Grade 1" : "Grade 2 or below";
System.out.println("Grade: " + grade); // Grade 1
// Cannot be used for void method calls (only expressions that produce a value).
// Use it inside variable assignments or return statements.
boolean isElite = (cursedEnergy >= 400000);
System.out.println("Is elite: " + isElite); // true
}
}
javac AssignTernaryDemo.java java AssignTernaryDemo After Black Flash: 350000 After depletion: 270000 After domain expansion: 540000 Remainder: 40000 Grade: Grade 1 Is elite: true
Bitwise Operators
Operators that directly manipulate individual bits of an integer. Used in flag management, cryptographic processing, and low-level optimizations. They are rarely used in typical application code, but knowing how to read them is useful.
| Operator | Meaning | Example (decimal) | Example (binary) |
|---|---|---|---|
& | Bitwise AND (1 if both are 1) | 6 & 3 → 2 | 0110 & 0011 → 0010 |
| | Bitwise OR (1 if either is 1) | 6 | 3 → 7 | 0110 | 0011 → 0111 |
^ | Bitwise XOR (1 if different) | 6 ^ 3 → 5 | 0110 ^ 0011 → 0101 |
~ | Bitwise NOT (inversion) | ~6 → -7 | Inverts all bits. |
<< | Left shift (equivalent to ×2n) | 6 << 1 → 12 | 0110 → 1100 |
>> | Right shift (equivalent to ÷2n, preserves sign) | 6 >> 1 → 3 | 0110 → 0011 |
>>> | Unsigned right shift (fills with 0 including the sign bit) | -1 >>> 28 → 15 | Fills the most significant bit with 0. |
Common Mistake 1: Truncation in integer division
Division between two int values truncates the decimal part. This is a common mistake when calculating percentages or ratios.
IntDivNg.java
public class IntDivNg {
public static void main(String[] args) {
int total = 10;
int cleared = 3;
// int / int truncates the decimal.
double rate = total / cleared; // Expected: 3.333... Actual: 3.0
System.out.println("Clear rate: " + rate + "%"); // Prints 3.0% (unintended result)
}
}
javac IntDivNg.java java IntDivNg Clear rate: 3.0%
Cast one of the operands to double before dividing to get an accurate decimal result.
IntDivOk.java
public class IntDivOk {
public static void main(String[] args) {
int total = 10;
int cleared = 3;
// Casting with (double) before dividing gives a decimal result.
double rate = (double) total / cleared;
System.out.println("Clear rate: " + rate); // 3.3333333333333335
}
}
javac IntDivOk.java java IntDivOk Clear rate: 3.3333333333333335
Common Mistake 2: Using == to compare String or wrapper objects
== is used for comparing the values of primitive types. When applied to objects such as String or Integer, it compares references (memory locations) rather than values, so two objects with the same content can still return false.
EqualityNg.java
public class EqualityNg {
public static void main(String[] args) {
String name1 = new String("乙骨憂太");
String name2 = new String("乙骨憂太");
// == compares references; even with the same content, it may return false.
System.out.println(name1 == name2); // false (different references)
System.out.println(name1.equals(name2)); // true (same content)
}
}
javac EqualityNg.java java EqualityNg false true
Common Mistake 3: Confusion over operator precedence and string concatenation
Expressions are evaluated left to right. When mixing strings and numbers with +, once a string appears, all subsequent + operators become string concatenation. Use parentheses when you want numeric calculation to happen first.
PriorityNg.java
public class PriorityNg {
public static void main(String[] args) {
int grade = 2;
int section = 5;
// Once a string appears first, all subsequent + operators become concatenation.
System.out.println("Total: " + grade + section); // Total: 25 (intended: Total: 7)
}
}
javac PriorityNg.java java PriorityNg Total: 25
Wrap the numeric expression in parentheses () to perform the calculation first.
PriorityOk.java
public class PriorityOk {
public static void main(String[] args) {
int grade = 2;
int section = 5;
// Parentheses force the numeric addition before string concatenation.
System.out.println("Total: " + (grade + section)); // Total: 7
}
}
javac PriorityOk.java java PriorityOk Total: 7
Notes
The most important thing to remember about arithmetic operators is that dividing two int values with / truncates the decimal part. For example, 7 / 2 produces 3, not 3.5. When an accurate decimal is needed, cast at least one operand to double ((double) a / b) before the division.
The + used for string concatenation acts as string concatenation when either operand is a String. Because expressions are evaluated left to right, you must wrap numeric sub-expressions in parentheses () if you want arithmetic to happen before concatenation. When concatenating many strings in a loop, using StringBuilder.append() is more efficient than repeatedly using +.
The logical operators && and || perform short-circuit evaluation. Because && does not evaluate the right side when the left side is false, you can safely write obj != null && obj.method() by placing the null check first. Similarly, || skips the right side when the left side is true. For applications to conditional branching, see if / else if / else.
If you find any errors or copyright issues, please contact us.