2

I'm preparing a project for college where I need to write a custom made exception that will be thrown by a couple of classes in the same package when they were not initialized properly. The problem is that I must let the user know which of those classes wasn't initialized properly (and throwed the exception)... So I was thinking about something like this:

class InitializationException extends Exception {

private static final String DEFAULT_MSG =
            "This " + CLASSNAME-THROWINGME + " had not been initialized properly!";

    protected String msg;

InitializationException() {
    this.msg = DEFAULT_MSG;
}

    InitializationException(String msg) {
    this.msg = msg;
}
}

(btw, can it be achieved via reflection?)

y0n1
  • 166
  • 1
  • 9

6 Answers6

7

Look at Throwable.getStackTrace(). Each StackTraceElement has getClassName(). You can look at element [0] to determine the origination of the exception.

Dilum Ranatunga
  • 13,254
  • 3
  • 41
  • 52
1

Something like:

StackTraceElement[] trace = theException.getStackTrace();
String className = trace[0].getClassName();

(Though I'm not quite sure whether you want the first element or the last in the trace.)

(And note that you can create a Throwable and do getStackTrace() on it, without ever throwing it, to find out who called you (which would be trace element 1).)

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • You want the first one. The API says 'The zeroth element of the array (assuming the array's length is non-zero) represents the top of the stack, which is the last method invocation in the sequence. Typically, this is the point at which this throwable was created and thrown' – Dilum Ranatunga May 02 '13 at 17:08
  • @DilumRanatunga - Yeah, I'd have figured it out but I was racing to beat you. Didn't succeed, though. – Hot Licks May 02 '13 at 17:09
  • Nice tip about the unthrown `Throwable`. Answers the age old question "If an exception is instantiated but never thrown, was there really an exception?" The answer is "only if you called getStackTrace() to acknowledge its existence" :) – Dilum Ranatunga May 02 '13 at 17:16
1

I would just pass the throwing class into the constructor, like this:

public class InitializationException extends Exception {

    public InitializationException(Class<?> throwingClass) { ... }

    ...
}
1
class InitializationException extends Exception {
    private final String classname;
    InitializationException(String msg, Object origin) {
        super(msg);
        this.classname = origin != null ? origin.getClass().toString() : null;
    }
    public String getClassname() {
        return this.classname;
    }
}

. . . . throw new InitializationException("Something went wrong", this);

0

Its a workaround:

you could pass the classname within the Constructor, something like

throw new  InitializationException(getClass().getName());

or may be call the class like

throw new InitializationException(this);

and handle the name extraction in your excpetin class

 InitializationExcpetion(Object context){ 
this.name = getClass().getName() 
}
MemLeak
  • 4,456
  • 4
  • 45
  • 84
  • `getEnclosingClass()` is used for inner classes. If the class constructing the exception is not an inner class, this will be `null`. See http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getEnclosingClass() – Dilum Ranatunga May 02 '13 at 17:10
0

The answer is you force the class throwing the exception to tell the exception which class it is:

public class InitializationException extends Exception {

    public InitializationException(Class<?> c) {
        super( "The class " + c.getName()+ " had not been initialized properly!");
    }
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722