Branching with if, else, and switch
Apex, like Java, uses if/else if/else chains to branch execution based on boolean expressions. Because Apex runs on Salesforce's multitenant platform, every branch you write should also consider bulk-safety: conditionals inside loops over trigger.new must not contain SOQL or DML, since that logic runs once per record and can blow through governor limits.
Cricket analogy: A captain deciding whether to review an umpire's decision is exactly an if/else: if there are DRS reviews remaining and the batter is confident, call for the review, else accept the decision and move on.
public class OpportunityStageEvaluator {
public static String classify(Opportunity opp) {
if (opp.Amount == null) {
return 'Unqualified';
} else if (opp.StageName == 'Closed Won') {
return 'Won';
} else if (opp.Amount > 100000 && opp.Probability > 60) {
return 'Hot';
} else {
return 'Standard';
}
}
public static String classifyWithSwitch(String stage) {
switch on stage {
when 'Prospecting', 'Qualification' {
return 'Early';
}
when 'Negotiation/Review' {
return 'Late';
}
when else {
return 'Unknown';
}
}
}
}Apex's switch statement (introduced in the switch on syntax) is often clearer than a long if/else chain when comparing one variable against several discrete values, including sObject types, enums, and comma-separated value lists in a single when block. Unlike Java, Apex's switch does not fall through between when blocks, so you never need a break statement, which removes a common source of bugs.
Cricket analogy: A switch on the day's pitch report reads like: when 'Green top', bowl first; when 'Dry and cracked', bat first and expect spin later; when else, follow the toss-winner's default instinct.
As of recent API versions, Apex also supports the ternary operator (condition ? valueIfTrue : valueIfFalse) for compact single-expression assignments, which is handy inside SOQL WHERE clause construction or field assignment but should be avoided when it hurts readability.
for, while, and do-while loops
Apex supports three loop forms: the traditional three-part for loop (for (Integer i = 0; i < 10; i++)), the enhanced for loop that iterates a List, Set, or query result directly (for (Account a : accountList)), and while/do-while loops for condition-driven iteration. The enhanced for loop is the idiomatic choice when iterating sObject collections or SOQL results because it avoids manual index management and reads closer to plain English.
Cricket analogy: An enhanced for loop over a batting lineup is like a scorer going through each batter in order without tracking a slot number, just processing each one as they come to the crease.
// Enhanced for loop over a SOQL query result
List<Account> highValueAccounts = [
SELECT Id, Name, AnnualRevenue FROM Account WHERE AnnualRevenue > 1000000
];
for (Account acc : highValueAccounts) {
acc.Rating = 'Hot';
}
update highValueAccounts;
// Traditional for loop when the index itself matters
for (Integer i = 0; i < highValueAccounts.size(); i++) {
System.debug('Row ' + i + ': ' + highValueAccounts[i].Name);
}
// while loop draining a queue-like list
List<Case> retryQueue = new List<Case>(casesToRetry);
Integer attempts = 0;
while (!retryQueue.isEmpty() && attempts < 3) {
Case c = retryQueue.remove(0);
attempts++;
}The single biggest mistake Apex beginners make with loops is placing SOQL queries or DML statements (insert, update, delete) inside the loop body. Salesforce enforces per-transaction limits of 100 SOQL queries and 150 DML statements, so a trigger looping over 200 records with a query per iteration fails immediately. The correct bulk pattern is to query once before the loop, collect changes in a list inside the loop, and perform a single DML call after the loop.
Cricket analogy: A tea-break isn't called after every single delivery, one break serves the whole session, just as DML should run once after the loop, not once per iteration inside it.
SOQL-inside-a-for-loop and DML-inside-a-for-loop are the two most common causes of 'Too many SOQL queries: 101' and 'Too many DML statements: 151' governor limit exceptions. Always query collections before the loop and perform DML once after it, using Maps keyed by Id when you need to correlate records across multiple lists.
break, continue, and labeled loops
Apex supports break to exit a loop entirely and continue to skip to the next iteration, both borrowed from Java syntax. Apex also supports labeled loops (outerLoop: for (...) { ... }), letting break outerLoop; or continue outerLoop; control an outer loop from inside a nested inner loop, which is useful when validating nested collections such as Opportunities and their OpportunityLineItems.
Cricket analogy: A bowler taken off mid-over after conceding three consecutive boundaries is like a break statement, the over ends early instead of running its full six deliveries.
- if/else if/else chains branch on boolean expressions; switch on is often clearer for one variable against several discrete values and never falls through.
- Apex's switch on supports comma-separated values in a single when block and a when else default, with no break needed.
- The enhanced for loop (for (Type t : collection)) is the idiomatic way to iterate Lists, Sets, and SOQL results.
- Never place SOQL queries or DML statements inside a loop body; query once before, collect changes in a list, then perform one DML call after the loop.
- Governor limits cap transactions at 100 SOQL queries and 150 DML statements, and non-bulkified loops are the most common way to exceed them.
- break exits a loop entirely; continue skips to the next iteration; labeled loops let break/continue target an outer loop from a nested inner loop.
- while and do-while loops suit condition-driven iteration where the number of passes isn't known up front, such as draining a retry queue.
Practice what you learned
1. Why does placing a SOQL query inside a for loop over trigger.new risk a runtime exception?
2. What is the key behavioral difference between Apex's switch on and Java's switch statement?
3. Which loop form is most idiomatic for iterating a List<Account> in Apex?
4. What does the bulk-safe pattern for DML inside a trigger loop look like?
5. What is the effect of a labeled continue statement, e.g. continue outerLoop;, inside a nested loop?
Was this page helpful?
You May Also Like
Lists, Sets, and Maps
Master Apex's three core collection types — ordered Lists, unique Sets, and key-value Maps — and when to use each for bulk-safe, governor-limit-friendly code.
sObjects and DML
Understand Apex's sObject data model and the insert, update, upsert, and delete DML operations used to change Salesforce records, including bulk patterns and exception handling.
SOQL Queries
Learn Salesforce Object Query Language (SOQL) syntax for retrieving records, including relationship queries, aggregate functions, and governor-limit-aware query design.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics