2

Suppose I have the following Class:

public class Yup{

    public class YupException extends Exception{}//END YupException

    public static void debugTestException(){
        YupException TestException=new YupException('This is only a test.');

        system.debug(system.LoggingLevel.ERROR,'TestException                       = '+TestException                       );
        system.debug(system.LoggingLevel.ERROR,'TestException.getCause()            = '+TestException.getCause()            );
        system.debug(system.LoggingLevel.ERROR,'TestException.getMessage()          = '+TestException.getMessage()          );
        system.debug(system.LoggingLevel.ERROR,'TestException.getTypeName()         = '+TestException.getTypeName()         );
        system.debug(system.LoggingLevel.ERROR,'TestException.getStackTraceString() = '+TestException.getStackTraceString() );
        system.debug(system.LoggingLevel.ERROR,'TestException.getLineNumber()       = '+TestException.getLineNumber()       );
    }//END DebugTestException()

}//END Yup

and execute the following code anonymously:

Yup.debugTestException();

I get:

Yup.debugTestException() Results

  1. How does new YupException('This is only a test.'); compile without having the constructor public YupException(string ErrorMessage){ ... }?
  2. Similarly, how does YupException compile when I haven't implemented any of the methods mention in Yup.debugTestException()?
  3. How do those unwritten methods and constructor actually execute / How do I get away implementing an Interface while not implementing any of it's methods let alone call an undefined constructor??

Here's primary documentation from Salesforce, but what does SFDC do on the backend that makes my inner-compiler-alarm go off?

4

An exception is a virtual class, I would assume, given that it can be extended. From the documentation for extending a class:

A class that extends another class inherits all the methods and properties of the extended class. In addition, the extending class can override the existing virtual methods by using the override keyword in the method definition. Overriding a virtual method allows you to provide a different implementation for an existing method. This means that the behavior of a particular method is different based on the object you’re calling it on. This is referred to as polymorphism.

What I take from that is that you can use all of the methods from the Exception class, in addition to what you want to add-on by override. To answer your questions, it compiles and executes because Exception has a constructor and its own methods that are already wired up to Salesforce error handling.

4

How does new YupException('This is only a test.'); compile without having the constructor public YupException(string ErrorMessage){ ... }?

Similarly, how does YupException compile when I haven't implemented any of the methods mention in Yup.debugTestException()?

All those methods are part of the Exception class:

global abstract class Exception {
    global Exception() {
        // implementation
    }

    global Exception(String message) {
        this();
        // implementation
    }

    global String getCause() {
        // implementation
    }

    global String getMessage() {
        // implementation
    }

    global String getTypeName() {
        // implementation
    }

    global String getStackTraceString() {
        // implementation
    }

    global Integer getLineNumber() {

    }
}

We can almost safely assume that the Exception class is abstract, because it can't be constructed despite having global constructors (although, that could just be a compiler-enforced limit).

When you extend any Exception, your class automatically inherits all of its members, functions, and constructors, which is why your "do-nothing" class actually does quite a bit without any work on your part.

How do those unwritten methods and constructor actually execute / How do I get away implementing an Interface while not implementing any of it's methods let alone call an undefined constructor??

You're not "implementing", you're "extending". Implementation is for interfaces, which an Exception is not. Extending is for classes, and is how one class takes on the properties of another while being able to have its own additional properties.

Here's primary documentation from Salesforce, but what does SFDC do on the backend that makes my inner-compiler-alarm go off?

There's really nothing magical about this design. Think of it as a closed-source library that you only have a symbol-table for. You can extend the classes and call the stock methods, but you can't override them or examine them.

  • But there is a generic Exception class that works all by itself, I thought abstract classes had to be extended, that they couldn't stand alone? – greenstork May 22 '14 at 23:34
  • When you try catch a generic Exception, it is never a base Exception. It will always be some subclass of Exception, such as NullPointerException, DMLException, etc. there is never a time I have observed a literal Exception. You can cast a subclass into a superclass, which is why you can catch Exception, but they will never be constructed. – sfdcfox May 23 '14 at 0:31
  • I very often catch a generic (Exception e) – greenstork May 23 '14 at 15:46
  • public class Demo { abstract class a {} class b extends a {} public static void demo() { b var = new b(); a var2 = var; /* no cast required */ a var3 = new a(); /* compiler error: type cannot be constructed */ } }. An abstract class can be a placeholder for its children, but cannot itself be constructed. In this way, Exception itself acts as a polymorphic placeholder for all of its descendants, but you will never see an exception that is not a subclass of exception. – sfdcfox May 23 '14 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.