Development
Basics of Apex Coding Interview Questions and Answers Experienced
1. What is the difference between instance and static variables in Apex?
Ans:
Instance variables are specific to each object of a class, while static variables are shared among all instances.
Example:
public class Example {
public Integer instanceVar; // Instance variable
public static Integer staticVar; // Static variable
}
Example e1 = new Example();
e1.instanceVar = 10; // Access instance variable via object
Example.staticVar = 100; // Access static variable via class name
Example e2 = new Example();
System.debug(e2.instanceVar); // null, as it's a new instance
System.debug(Example.staticVar); // 100, shared across instances
2. Explain method overloading in Apex with an example.
Ans:
Method overloading allows multiple methods within the same class to have the same name but different parameter types, different number of parameters, or a different order of parameters. The compiler determines which method to call based on the arguments provided.
Example:
public class MathOps {
public Integer add(Integer a, Integer b) {
return a + b;
}
public Double add(Double a, Double b) {
return a + b;
}
public Integer add(Integer a, Integer b, Integer c) {
return a + b + c;
}
}
MathOps calc = new MathOps();
System.debug(calc.add(5, 10)); // Calls the Integer add method
System.debug(calc.add(5.5, 10.5)); // Calls the Double add method
System.debug(calc.add(1, 2, 3)); // Calls the three-parameter Integer add method
3. What is polymorphism? Give example with method overriding.
Ans:
Polymorphism (meaning "many forms") is a core OOP concept that allows objects to take on different forms. In Apex, it primarily refers to the ability of an object to appear as one type while actually being another. Method overriding is a form of runtime polymorphism where a subclass provides a specific implementation for a method that is already defined in its superclass.
Example:
public virtual class Animal {
public virtual void sound() {
System.debug('Animal makes a sound');
}
}
public class Dog extends Animal {
public override void sound() {
System.debug('Dog barks');
}
}
public class Cat extends Animal {
public override void sound() {
System.debug('Cat meows');
}
}
Animal myAnimal1 = new Dog();
myAnimal1.sound(); // Outputs: Dog barks (runtime polymorphism)
Animal myAnimal2 = new Cat();
myAnimal2.sound(); // Outputs: Cat meows
26. What is DML in Apex? Explain common DML operations.
Ans:
DML stands for Data Manipulation Language. In Apex, DML statements are used to manipulate (insert, update, upsert, delete, undelete, merge) records in the Salesforce database. DML operations are performed on sObjects.
Common DML Operations:
- `insert`: Used to create new records in the database.
Example:Account newAcc = new Account(Name = 'New Test Account', Industry = 'Technology');
insert newAcc; // Inserts a single record
ListnewContacts = new List ();
newContacts.add(new Contact(FirstName = 'John', LastName = 'Doe', AccountId = newAcc.Id));
newContacts.add(new Contact(FirstName = 'Jane', LastName = 'Smith', AccountId = newAcc.Id));
insert newContacts; // Inserts a list of records (bulkification) - `update`: Used to modify existing records in the database.
Example:Account accToUpdate = [SELECT Id, Name FROM Account WHERE Name = 'New Test Account' LIMIT 1];
if (accToUpdate != null) {
accToUpdate.Name = 'Updated Test Account';
update accToUpdate; // Updates a single record
} - `upsert`: Used to either insert new records or update existing records based on a specified external ID or the record's ID. If a record with the specified ID or external ID exists, it's updated; otherwise, a new record is inserted.
Example:Account acc1 = new Account(Name = 'Upsert Demo', External_ID__c = 'EXT001'); // Assuming External_ID__c is an External ID field
Account acc2 = new Account(Name = 'Upsert Existing', External_ID__c = 'EXT002');
ListaccountsToUpsert = new List {acc1, acc2};
upsert accountsToUpsert External_ID__c; // Upserts based on External_ID__c - `delete`: Used to remove records from the database. Deleted records go to the Recycle Bin.
Example:Account accToDelete = [SELECT Id FROM Account WHERE Name = 'Updated Test Account' LIMIT 1];
if (accToDelete != null) {
delete accToDelete;
} - `undelete`: Used to restore records from the Recycle Bin.
Example:// First, get the Id of a record that was recently deleted
// (You'd typically store this ID or query all deleted records).
// ListdeletedAccounts = [SELECT Id, Name FROM Account ALL ROWS WHERE IsDeleted = true LIMIT 1];
// if (!deletedAccounts.isEmpty()) {
// undelete deletedAccounts;
// } - `merge`: Used to merge up to three records of the same SObject type into one record. The merged records are deleted, and their related records are reparented to the master record.
Example:// Account masterAccount = [SELECT Id FROM Account WHERE Name = 'Master Account' LIMIT 1];
// Account duplicateAccount = [SELECT Id FROM Account WHERE Name = 'Duplicate Account' LIMIT 1];
// if (masterAccount != null && duplicateAccount != null) {
// merge masterAccount duplicateAccount;
// }
27. What is `try-catch-finally` in Apex? When do you use it?
Ans:
`try-catch-finally` is an essential construct in Apex (and many other programming languages) for handling exceptions. It allows you to gracefully manage errors that occur during the execution of your code, preventing unexpected crashes and providing a mechanism for error recovery or logging.
- `try` block:
- Contains the code that might potentially throw an exception (e.g., DML operations, SOQL queries, external callouts).
- If an exception occurs within the `try` block, execution immediately jumps to the `catch` block.
- `catch` block:
- Catches and handles specific types of exceptions.
- It takes an exception type as an argument (e.g., `DmlException`, `QueryException`, `Exception` for a generic catch-all).
- You can have multiple `catch` blocks to handle different exception types differently.
- Contains code to log the error, display a user-friendly message, or attempt to recover from the error.
- `finally` block (Optional):
- Contains code that will *always* execute, regardless of whether an exception occurred or was caught.
- Typically used for cleanup operations, such as closing resources, rolling back non-database changes, or ensuring certain final actions are taken.
- The `finally` block executes even if a `return` statement is encountered in the `try` or `catch` block.
- DML Operations: To handle errors during `insert`, `update`, `delete`, etc. (e.g., validation rule failures, duplicate record errors).
- SOQL/SOSL Queries: To catch `QueryException` if a query returns no records or an invalid query is constructed.
- External Callouts: To handle network errors, timeouts, or unexpected responses from external systems.
- Data Validation: When processing user input or external data where unexpected formats or values might cause runtime errors.
- Resource Management: To ensure that resources are properly closed or reset, even if an error occurs.
- Logging and Error Reporting: To log detailed error information for debugging and to provide graceful error messages to users.
public class ExceptionHandlingDemo {
public void createAccountSafely(String accName) {
Account newAccount;
try {
if (accName == null || accName.trim() == '') {
throw new DmlException('Account Name cannot be empty.');
}
newAccount = new Account(Name = accName);
insert newAccount;
System.debug('Account created successfully: ' + newAccount.Name);
} catch (DmlException e) {
System.debug('DML Exception caught: ' + e.getMessage());
System.debug('Specific DML Error: ' + e.getDmlMessage(0));
} catch (Exception e) {
System.debug('Generic Exception caught: ' + e.getMessage());
} finally {
System.debug('Finally block executed. Cleanup or final logging here.');
}
}
}
// Test in Anonymous Window:
// new ExceptionHandlingDemo().createAccountSafely('My New Company');
// new ExceptionHandlingDemo().createAccountSafely(''); // Will trigger DmlException
28. What is the difference between `System.debug()` and `System.assert()`?
Ans: Both `System.debug()` and `System.assert()` are utility methods in Apex, but they serve very different purposes.
- `System.debug(expression)`:
- Purpose: Used for debugging and inspecting the values of variables, expressions, or the flow of execution within Apex code.
- Behavior: Prints information to the debug log. The log level for `Apex Code` and `System` must be set to `Debug` or `Finest` to see these messages.
- Usage: Typically used during development and troubleshooting to understand what your code is doing. These statements should generally be removed or commented out in production code to avoid unnecessary log generation.
- No Impact on Execution Flow: `System.debug()` statements do not affect the normal execution flow of your code.
Integer x = 10;
String name = 'Alice';
System.debug('Value of x: ' + x);
System.debug('Name: ' + name + ', Length: ' + name.length()); - `System.assert(condition, message)`:
- Purpose: Used primarily in Apex test classes to verify that a certain condition is true. If the condition is false, the assertion fails, and the test method stops executing and is marked as failed.
- Behavior: It checks if a boolean condition is true. If false, it throws an `AssertionFailedException`, indicating that the expected behavior of the code was not met.
- Usage: Essential for writing effective unit tests to confirm that your code behaves as expected under various scenarios. It helps ensure code quality and prevent regressions.
- Impact on Execution Flow: If an assertion fails, the test method fails, and further execution of that test method is halted.
- `System.assertEquals(expected, actual, message)`: Asserts that two values are equal.
- `System.assertNotEquals(expected, actual, message)`: Asserts that two values are not equal.
@IsTest
private class MyCalculatorTest {
static testMethod void testAddMethod() {
Calculator calc = new Calculator();
Integer result = calc.add(5, 3);
System.assertEquals(8, result, 'The add method should return 8 for 5 + 3.');
System.assertNotEquals(9, result, 'The result should not be 9.');
}
}