Java Operators and Booleans
Calculate values, compare them, and combine facts into a rule you can explain. Learn why boundaries, grouping, and the order of a safety check matter as much as choosing the right operator.
Before you start: complete Java Type Casting and Numeric Conversion. Each example is a complete Main.java program in the existing Java 21 runner. Predict, run, and then edit one value. You do not need an if statement to calculate a boolean.
What you will be able to do
- Predict arithmetic results, including integer division and remainder.
- Distinguish assigning a value from comparing two values.
- Turn boundary requirements into clear boolean expressions.
- Combine conditions using &&, ||, and !.
- Use short-circuit guards in a safe evaluation order.
- Test an eligibility rule with passing, failing, and exact-boundary inputs.
An operator helps an expression produce a result
An expression is a piece of code that produces a value, such as 2 + 3 or completedLessons >= 3. An operator specifies an operation, and its operands are the values or expressions it works on. In 2 + 3, the plus sign adds the two operands and produces an int result. A comparison instead produces a boolean result: true or false.
This lesson uses a workshop with a limited number of seats. You will calculate counts, ask whether a learner meets a requirement, and combine that answer with other facts. You can print a boolean or store it in a variable without writing an if statement. Branching comes later; first, make sure the condition itself expresses the correct rule.
A true result describes this calculation with these inputs. It does not reserve a seat, verify an account, or enforce access on a server. These are fixed-data learning examples. In a real application, rules must be checked where the protected action happens, using trusted current data.
Arithmetic: count full groups and what remains
Use + for addition, - for subtraction, * for multiplication, / for division, and % for remainder. In our packing example, 17 items divided into groups of four gives four complete groups with one item remaining. The integer quotient is 4 and the remainder is 1, so the two operations answer different questions about the same numbers.
The remainder operator is not a percentage operator. A percentage needs a ratio and a suitable scale, as you practised in the casting lesson. With integers, division truncates toward zero, and a nonzero remainder has the dividend's sign. For example, -17 % 4 is -1, not 3. Our packing inputs are deliberately nonnegative, so negative packing rules are not being invented here.
Predict what happens with 16 items and then with 3 items. Exact packing leaves a remainder of zero; fewer items than the box size gives zero full boxes. A box size of zero makes integer division or remainder fail with ArithmeticException. Also remember that integer arithmetic can overflow; an operator does not remove the type limits from earlier lessons.
Main.java · Pack items and explain the remainder
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Items after adding two: 19
Items after removing two: 15
Items in three full boxes: 12
Full boxes: 4
Items left over: 1
Check the packing predictions
At 16 items, four full boxes leave zero items. At three items, zero full boxes leave three items. These answers describe complete groups, not a rounded-up shipping box count.
Assignment updates a value; comparison asks a question
The single equals sign = assigns a value. The two-character operator == compares suitable values for equality. Writing seats = 6 changes the variable; writing seats == 6 produces an answer without changing seats. This distinction is especially important for booleans, because an accidental boolean assignment can compile inside an expression while silently changing state.
Compound assignments such as +=, -=, *=, /=, and %= combine an operation with an update. Here, seats -= 2 reduces the count from 8 to 6. The ++ and -- operators increment or decrement by one. The example keeps each update on its own line so the changing state is easy to trace before reading the next output.
For our int values, these updates behave as the corresponding simple arithmetic assignment would. More generally, compound assignment can include an implicit conversion, so it is not always identical to spelling out an assignment for every type. Keep the variable type and range in mind, and do not use a compact operator to hide an unwanted narrowing conversion.
Main.java · Assignment changes the stored value
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
After two reservations: 6
After one cancellation: 7
After another reservation: 6
After adding capacity: 9
Comparisons turn a boundary into true or false
The operators <, <=, >, and >= compare numeric values. == tests equality, while != tests inequality. A rule saying at least three lessons needs >= 3, not > 3. A learner with exactly three completed lessons is the boundary case that reveals this difference immediately.
The program prints all six comparisons at the exact minimum. Read each label before predicting the result. The value can simultaneously meet the minimum, equal the minimum, and be at most the minimum. Those descriptions are not contradictions; they are different questions asked about the same number.
For a numeric interval, write both comparisons, such as score >= 0 && score <= 100. Java does not support an algebra-style chained comparison such as 0 <= score <= 100. Also, =< and => are not Java comparison operators. Test one value below a threshold, the threshold itself, and one above it before trusting your condition.
Main.java · Test the exact course boundary
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Meets minimum: true
Above minimum: false
Exactly minimum: true
Different from minimum: false
Still below minimum: false
At most minimum: true
Check the minimum-boundary experiment
For two, three, and four completed lessons, the meets-minimum result is false, true, true. The above-minimum result is false, false, true. The single equality case is the important difference.
Combine facts: both, either, or not
The && operator means both boolean operands must be true. Use it when the rule requires coursework readiness and a seat. The || operator means at least one operand must be true. It is inclusive: if both coursework readiness and a pass qualify as alternatives, having both still satisfies the rule.
The ! operator reverses a boolean value. With suspended set to false, !suspended is true. Choose names that make the expression readable: courseworkReady && seatAvailable is easier to explain than a long series of comparisons to true. With a primitive boolean flag, flag == true is usually unnecessary; just use flag.
Work through the four combinations below. For &&, only true with true succeeds. For ||, only false with false fails. Negation applies to its operand: !(a && b) means it is not the case that both are true, which is different from !a && !b. Parentheses help make the intended group visible.
truewithtrue: AND givestrue; OR givestrue.truewithfalse: AND givesfalse; OR givestrue.falsewithtrue: AND givesfalse; OR givestrue.falsewithfalse: AND givesfalse; OR givesfalse.
Main.java · Both, either, and not
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Coursework and seat: false
Coursework or pass: true
Not suspended: true
Short-circuit AND can protect a later operation
Java evaluates the left operand of && first. If it is false, the whole AND is already false, so Java does not evaluate the right operand. In this example, sessionCount > 0 is false. The division on the right is skipped, and the program safely prints false instead of dividing by zero.
The order is part of the protection. Putting totalMinutes / sessionCount first would attempt division before the guard can help. Replacing && with a single & also evaluates both boolean operands, so it does not provide this short-circuit guard. Single & has legitimate uses, but is not an interchangeable spelling of &&.
Change the session count to 4: the guard passes and 20 / 4 >= 5 is true. At 5 sessions the guard passes but the second test is false. The condition still uses integer division deliberately. If a fractional average is required, apply the conversion lesson before choosing the comparison rule. A false result should be interpreted according to which requirement failed.
Main.java · Check the denominator before dividing
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Enough practice: false
Short-circuit OR stops when the first answer is enough
Java evaluates the left operand of || first and skips the right when the left is true. Here note == null is true, so Java never calls length on the missing reference. The rule safely answers whether the note is missing or empty. It does not replace the note or create a String object.
If note is an empty String, the null check is false, so length is evaluated and returns zero. If note contains text, both tests are false. Notice that whitespace-only text is not empty according to this rule. A rule that rejects blank notes would need additional text processing, which belongs to the Strings lesson.
A single | on boolean operands evaluates both sides, so it cannot protect the null method call here. The boolean ^ operator means exactly one side is true and also evaluates both sides; it is not inclusive OR. Integer bitwise and shift operations are separate topics and are not needed for this workshop condition. Use && and || for these short-circuit combinations.
Main.java · Stop after finding a missing note
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Missing or empty: true
Test missing, empty, and nonempty notes
The result is true for null, true for an empty String, and false for the text Ready. Replacing || with | makes the null case throw NullPointerException. A space-only String is nonempty under this deliberately narrow rule.
Parentheses should reflect the actual rule
In arithmetic, multiplication, division, and remainder bind more tightly than addition and subtraction. In these boolean expressions, ! binds more tightly than &&, and && binds more tightly than ||. Thus hasPass || courseworkReady && !suspended is grouped as hasPass || (courseworkReady && !suspended).
That ungrouped rule allows a pass holder through even when suspended. Our intended rule says either a pass or coursework can establish the access route, but every learner must also be not suspended. Writing (hasPass || courseworkReady) && !suspended makes that requirement explicit. Parentheses are not decoration here: they change the answer for the example's inputs.
Precedence describes grouping, not a rule that Java simply runs the highest-precedence operation first regardless of evaluation order. Java evaluates operands left to right under its expression rules, and short-circuit operators may skip work. Keep side effects out of complex conditions, use meaningful intermediate booleans, and prefer an expression you can explain in one sentence.
Main.java · Group the policy that you actually mean
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Ungrouped rule: true
Intended rule: false
Without arithmetic grouping: 14
With arithmetic grouping: 20
Equality depends on the values you are comparing
For our primitive integer counts and boolean flags, == tests their values. For object references such as String variables, == tests whether the references identify the same object, not whether their text contents match. The example intentionally constructs two different String objects with the same text so reference equality is false while equals returns true.
String literals may share objects, so testing == on a few quoted literals can make the wrong text-comparison strategy appear to work. Use a suitable content-comparison method when you mean text equality. Calling equals on a null receiver still fails; the upcoming Strings lesson will show practical approaches to nullable text.
Floating-point equality also deserves care. == tests the represented numeric values, not whether a human would round them to the same printed decimal. The earlier 0.1 + 0.2 example is not exactly equal to 0.3. There is no universal tolerance that is right for every measurement or money rule, so do not replace every comparison with an arbitrary small number.
Main.java · Text equality is not reference equality
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Same reference: false
Same text: true
Exactly 0.3: false
Optional: prefix and postfix return different values
Both count++ and ++count increase count by one, but their expression results differ. Postfix count++ produces the old value, then leaves count incremented. Prefix ++count produces the updated value. The example stores those results separately to make the difference visible without combining several changes in one hard-to-read expression.
Starting from 3, previous receives 3 and count becomes 4. The prefix expression then increments count to 5 and gives updated the value 5. The extra output lines show the stored count independently from the value captured by the expression. This is a useful way to check your understanding rather than guessing from one line of output.
When the increment stands alone as a statement, both forms leave the same updated count. Prefer that simple style while learning. Avoid incrementing a value inside a comparison or mixing several increments into a calculation; even when the behavior is defined, the code becomes harder to review and boundary-test.
Main.java · Prefix and postfix return different values
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Postfix captured: 3
Count after postfix: 4
Prefix captured: 5
Count after prefix: 5
Repair the exact boundary and the shared restrictions
A learner qualifies with a pass or at least three completed lessons, but everyone also needs a positive seat count and must not be suspended. The starter rejects exactly three lessons and lets pass holders bypass the final restrictions. Repair the boolean expression without changing the inputs.
Main.java · Repair the eligibility rule
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Reveal the explained repair
Use >= to include exactly three completed lessons. Group the alternative access routes before requiring a positive seat count and no suspension. The original rule compiles, but hasPass sits outside the shared restrictions because && binds more tightly than ||. Retest with hasPass true and suspended true: the repaired rule must still deny eligibility.
Main.java · Repaired eligibility rule
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Can reserve: true
Independent lab: a readable workshop eligibility report
Build a fixed-data workshop eligibility report. A pass OR at least three completed lessons establishes an access route. A positive seat count AND no suspension are required for every learner. This exercise computes a local boolean only; it does not reserve anything or implement real authorization.
- Use boolean hasPass = false, int completedLessons = 3, int seatsAvailable = 1, and boolean suspended = false.
- Declare final int REQUIRED_LESSONS = 3 and calculate courseworkReady using the inclusive minimum.
- Calculate accessRoute as having a pass OR coursework readiness.
- Calculate seatAvailable from seatsAvailable > 0, then canReserve from accessRoute AND seatAvailable AND not suspended.
- Print the four labelled booleans in the expected output using the named intermediate results.
- Test below, at, and above the coursework threshold, then test a pass holder with no seats or a suspension.
Use this output contract to check your original inputs:
Coursework ready: true
Access route: true
Seat available: true
Can reserve: true
Main.java · Build your eligibility report
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
Show hints without revealing the solution
Start with one boolean for each named requirement. Use an inclusive comparison for coursework, || for the alternative route, and && for shared restrictions. Apply ! to suspended. Print the intermediate booleans so you can see why the final result changes.
Reveal the explained lab solution
Main.java · Eligibility report solution
Predict the result, edit Main.java, then run your program.
Standard input · optional
Select Run code to compile and execute this program.
At exactly three lessons, courseworkReady is true. A true coursework result makes accessRoute true even without a pass. The final rule also requires a seat and !suspended. Named intermediate booleans help explain a denial and reduce precedence mistakes. They are still snapshots of the values at calculation time, so changing an input later would require recalculating the dependent results.
Test changes and boundaries
Predict all four lines before each run. Reset between independent experiments.
- With no pass, test completedLessons 2, 3, and 4: final eligibility should be false, true, and true when the other requirements stay satisfied.
- Set completedLessons to 0 and hasPass to true: courseworkReady is false, but accessRoute and canReserve are true.
- Keep hasPass true and set suspended true: canReserve must be false regardless of the coursework count.
- Set seatsAvailable to 0, then -1: seatAvailable and canReserve must both be false, even for a pass holder.
- Set both access routes to false: a free seat alone must not make canReserve true. These boolean checks do not validate all possible input data or enforce concurrent seat availability.
Common mistakes and how to diagnose them
A condition can compile and still express the wrong policy. Check the input boundary, grouping, evaluation order, and whether a supposedly read-only expression changes state.
Using = where a comparison was intended
A boolean assignment can compile inside an expression and change the variable. Use == when you really need equality, or just read the boolean flag itself. Separate updates from conditions so unintended state changes are easier to notice.
The exact boundary fails
Translate at least as >= and more than as >. Test immediately below the minimum, at the minimum, and immediately above it. A few large passing values will not reveal an off-by-one comparison.
Division by zero or a null method call still happens
Put the safety check on the left of && or || as appropriate. Single & and | evaluate both operands. Reversing the guard and protected operation also defeats the protection, even with a short-circuit operator.
A pass holder bypasses a shared restriction
Read the grouping of mixed && and || carefully. If every access route requires a final restriction, group the alternatives first or store them in an intermediate boolean before applying that restriction.
Text comparison works sometimes and fails elsewhere
String == compares reference identity. Shared literal objects can mask the problem. Use content comparison for content rules and decide explicitly how missing references should be handled.
A boolean result appears out of date
Stored conditions do not automatically re-evaluate when their inputs change. Calculate after the relevant inputs are finalized or recalculate after an update. A variable holding true is not a permanently live connection to the original expression.
Frequently asked questions
Does || mean exactly one condition must be true?
No. It is inclusive OR: either or both can be true. Boolean ^ represents exactly-one logic, but it evaluates both operands and is not a short-circuit guard.
Can I use 1 or 0 as a condition in Java?
Java does not automatically treat integers as booleans. Write a meaningful comparison such as seatsAvailable > 0. The resulting expression is boolean; the original count remains int.
Are & and && interchangeable for booleans?
No. They can produce the same truth value when both operands complete normally, but & evaluates both operands. && skips the right operand when the left is false. That difference matters for exceptions, expensive calls, and side effects.
Do parentheses change the code or just make it clearer?
Both are possible. Some clarify existing grouping, while others change which operands an operator combines and therefore change the result. In a mixed pass-or-coursework rule, explicitly grouping the alternatives can fix a real bypass bug.
Does a true canReserve value actually reserve a seat?
No. This program computes and prints a result from fixed values. A real reservation needs trusted validation and a protected state change that handles competing requests. A local boolean is not authorization or persistence.
Make each condition answer a clear question
Use arithmetic to calculate, comparisons to ask questions, and boolean operators to combine the answers. Keep assignment separate, include the intended boundary, and put short-circuit guards before the operations they protect.
Before moving on, explain why a pass cannot override suspension in the lab and why replacing && with & can cause a runtime failure. Next is Java Strings, including practical content comparison and text operations.
Can you explain the rule, not just predict true?
Answer all six questions and read the reasoning. Results are temporary on this page and do not save course progress.
References and related learning
The workshop scenario, examples, explanations, and exercises are original SovranCode material. These official references support the language and API rules.
- Java 21 specification: arithmetic and remainder
- Java 21 specification: numerical comparison and equality
- Java 21 specification: conditional AND and OR
- Java 21 specification: evaluation order
- Java 21 String API: equals
Review numeric conversion · Review data types · Java course roadmap.
Last updated: