ProMind
SearchFor TeachersFor Parents
ProMind
Privacy PolicyTerms of ServiceRefund Policy

© 2025 DataGrid Softwares LLP. All rights reserved.

    Exceptions

    Flashcards for topic Exceptions

    Intermediate34 cardsGeneral

    Preview Cards

    Card 1

    Front

    What's wrong with the following loop pattern and why should it be avoided?

    try { int i = 0; while(true) range[i++].climb(); } catch (ArrayIndexOutOfBoundsException e) { }

    Back

    This code abuses exceptions for ordinary control flow - a serious anti-pattern because:

    1. It's drastically less efficient (roughly 2x slower) than standard loops
    2. It obfuscates the code's purpose, making it unreadable
    3. It prevents JVM optimizations that would normally occur in try-catch blocks
    4. It can mask real bugs by catching and ignoring legitimate errors

    The proper alternative is a standard loop:

    for (Mountain m : range) m.climb();

    Exceptions should only be used for exceptional conditions, not regular control flow.

    Card 2

    Front

    What is the "cardinal rule" for deciding between checked and unchecked exceptions, and what factors should influence this decision?

    Back

    Cardinal rule: Use checked exceptions for conditions from which the caller can reasonably be expected to recover.

    Decision factors:

    • Use checked exceptions when:

      • Recovery is possible
      • You want to force callers to handle the condition
      • The condition is a legitimate outcome (not a bug)
      • You can provide methods to help with recovery
    • Use runtime exceptions when:

      • The condition represents a programming error
      • Recovery is impossible or unlikely
      • Forcing exception handling would be burdensome
      • The condition results from precondition violations

    If it's unclear whether recovery is possible, favor unchecked exceptions.

    Remember: Checked exceptions increase API complexity but enhance reliability when used appropriately.

    Card 3

    Front

    Explain why overuse of checked exceptions in APIs can be problematic and describe two techniques to convert a checked exception into a more API-friendly alternative.

    Back

    Problems with overusing checked exceptions:

    • Forces clients to use try-catch blocks or propagate exceptions
    • Makes APIs less pleasant to use
    • Creates compatibility issues with functional interfaces and streams in Java 8+
    • Increases code verbosity
    • May force handling of conditions from which recovery is impractical

    Two conversion techniques:

    1. Return an Optional:
    // Instead of: public FileData readFile(File f) throws IOException { /*...*/ } // Consider: public Optional<FileData> readFile(File f) { try { // Read file return Optional.of(fileData); } catch (IOException e) { return Optional.empty(); } }
    1. Split into a state-testing method + action method:
    // Instead of one method throwing checked exception: public void action(Args args) throws CheckedException { /*...*/ } // Create two methods: public boolean actionPermitted(Args args) { /*...*/ } public void action(Args args) { // throws unchecked exception if needed if (!actionPermitted(args)) { throw new UncheckedExceptionVariant(); } // Perform action }

    The second approach is inappropriate for concurrent access without synchronization.

    Card 4

    Front

    What is the correct way to handle an exception that you intentionally want to ignore?

    Back

    If you must ignore an exception:

    1. Name the exception variable ignored to signal intent
    2. Include a comment explaining WHY it's safe to ignore
    3. Consider logging the exception for monitoring purposes

    Example:

    Future<Integer> f = exec.submit(planarMap::chromaticNumber); int numColors = 4; // Default; guaranteed sufficient for any map try { numColors = f.get(1L, TimeUnit.SECONDS); } catch (TimeoutException | ExecutionException ignored) { // Use default: minimal coloring is desirable, not required // Logging might be appropriate here for monitoring }
    Card 5

    Front

    What is the relationship between API documentation and failure atomicity? What should happen when this rule is violated?

    Back

    Relationship:

    • As a rule, API methods that throw exceptions should leave objects in their pre-invocation state (failure atomicity)

    When violated:

    • The API documentation should explicitly state what state the object will be left in
    • Documentation must clearly indicate any partial modifications or inconsistent states
    • This allows clients to implement appropriate recovery strategies

    Unfortunately, many existing APIs fail to properly document these behaviors, leading to unpredictable behavior when exceptions occur.

    Card 6

    Front

    What strategies can be used to achieve failure atomicity in methods?

    Back

    Strategies for achieving failure atomicity (ensuring objects remain in a consistent state after exception):

    1. Design immutable objects (Item 17)

      • If objects can't be modified after creation, they remain consistent
    2. Check parameters before performing operations

      • Validates inputs before any state modification occurs
      • Example: Checking stack is not empty before popping
    3. Order computations to fail before modifications

      • Perform operations that might fail before changing object state
      • Example: Comparing elements before adding to a TreeMap
    4. Make temporary copies of mutable data

      • Only modify the original data after all operations succeed
      • Example: Creating a copy of an array before sorting
    5. Recovery code in catch blocks

      • Restore original state when exceptions occur
    6. Write robust catch-finally blocks

      • Use finally blocks to restore invariants

    Failure atomicity is especially important for checked exceptions, from which callers are expected to recover.

    Card 7

    Front

    What are the best practices for documenting exceptions in Java APIs?

    Back

    Best practices for documenting exceptions:

    1. Document all exceptions, both checked and unchecked

      • Use Javadoc @throws tags for all possible exceptions
    2. Declare each checked exception individually in the throws clause

      • Never declare superclasses like Exception or Throwable
      • Don't declare unchecked exceptions in throws clause
    3. Document precisely when each exception is thrown

      • Clearly specify conditions that trigger each exception
    4. For interface methods, document unchecked exceptions thoroughly

      • This forms part of the interface's general contract
    5. For multiple methods throwing the same exception for the same reason:

      • Document the exception in the class's documentation comment
      • Example: "All methods in this class throw NullPointerException if a null object reference is passed in any parameter"
    6. Distinguish between checked and unchecked exceptions in documentation

      • The @throws tag without a throws clause provides a visual cue that an exception is unchecked

    Remember: Undocumented exceptions make it difficult or impossible for others to effectively use your classes and interfaces.

    Card 8

    Front

    What technique should be used to create exception classes that automatically generate high-quality detail messages?

    Back

    Technique for automatically generating high-quality detail messages in exceptions:

    1. Create constructors that capture failure parameters instead of just taking a string message
    2. Generate the detail message automatically in the constructor
    3. Store the parameters as fields for programmatic access

    Implementation example:

    public class RangeException extends RuntimeException { private final double minimum; private final double maximum; private final double value; /** * Creates an exception when a value is outside an allowed range. * * @param minimum The minimum allowed value * @param maximum The maximum allowed value * @param value The actual value provided */ public RangeException(double minimum, double maximum, double value) { // Generate a detailed message automatically super(String.format( "Value %f is outside allowed range [%f, %f]", value, minimum, maximum)); // Save parameters for programmatic access this.minimum = minimum; this.maximum = maximum; this.value = value; } // Accessor methods public double getMinimum() { return minimum; } public double getMaximum() { return maximum; } public double getValue() { return value; } }

    Benefits:

    • Forces capture of all relevant failure information
    • Centralizes message generation for consistency
    • Provides programmatic access to failure data
    • Makes it hard to create poorly-documented exceptions
    • Enables better debugging and error analysis
    Card 9

    Front

    Explain why an object might not be usable after catching a ConcurrentModificationException, and what this teaches us about failure atomicity guarantees.

    Back

    When a ConcurrentModificationException occurs:

    1. The object is likely in an inconsistent state due to concurrent modifications
    2. Some operations may have completed while others failed
    3. Internal invariants of the data structure may be violated
    4. The object's state is unpredictable and potentially corrupt

    Key insight about failure atomicity: Failure atomicity cannot be guaranteed in scenarios involving concurrency violations. This demonstrates an important limitation - atomicity guarantees only apply when the client follows the object's usage contract. When multiple threads modify an object without proper synchronization, the responsibility for maintaining consistency shifts to the client code.

    This teaches us that failure atomicity is a conditional guarantee that depends on proper usage patterns.

    Card 10

    Front

    What are the standard Java exceptions you should reuse in your APIs, when is each appropriate, and what benefits do they provide over custom exceptions?

    Back

    Standard Exceptions to Reuse

    1. IllegalArgumentException

      • When a non-null parameter value is inappropriate
      • Example: Negative values, invalid formatting strings
    2. IllegalStateException

      • When object state makes operation impossible
      • Example: Using uninitialized objects, calling next() on exhausted iterator
    3. NullPointerException

      • When null is passed where prohibited
      • Preferred over IllegalArgumentException specifically for null values
    4. IndexOutOfBoundsException

      • When an index parameter is out of range
      • Preferred over IllegalArgumentException specifically for index values
    5. ConcurrentModificationException

      • When concurrent modification is detected on objects not designed for it
      • Note: This is a best-effort detection, not guaranteed
    6. UnsupportedOperationException

      • When an object doesn't support an optional operation in its interface
      • Example: Calling add() on an unmodifiable collection

    Benefits of Reusing Standard Exceptions

    • Improved API learnability: Follows established conventions developers already know
    • Enhanced code readability: Communicates intent through familiar patterns
    • Reduced memory footprint: Fewer distinct exception classes to load
    • Better interoperability: Works smoothly with existing exception-handling code

    Important: Only reuse an exception if your use case precisely matches its documented semantics, not just based on its name.

    Showing 10 of 34 cards. Add this deck to your collection to see all cards.