Martin Nielsen
Martin Nielsen

Reputation: 2047

Getting a Method object representing the origin of an Exception

Is it possible in Java, to get a Method object representing the method in which an exception was thrown provided nothing but said exception?

Given the example:

public class Test {

    protected void toFail() throws Exception {
        throw new Exception();
    }

    protected void toFail(String someparameter) throws Exception {
        throw new Exception();
    }

    public static void main(String[] args) {
        try {
            new Test().toFail("");
        }catch(Exception ex){
            //Clever code here
        }
    }

}

What clever code would allow me to get a Method object representing the toFail(String) method? Assuming its even possible :)

Clarification: I need to uniquely identify the method that caused the exception, and i need to be able to create a reflection Method object from it. When i say uniquely i mean that i need to take the possibility of overloaded methods into account.

Upvotes: 1

Views: 1581

Answers (2)

icza
icza

Reputation: 417552

You can get the name of the class and method it was thrown from like this:

StackTraceElement ste = exception.getStackTrace()[0];

String className = ste.getClassName();
String methodName = ste.getMethodName();

But you can't get the Method object because the StackTraceElement does not record which of the methods with the same name.

You can get the possible Method objects (possible as with matching name) like this:

StackTraceElement ste = exception.getStackTrace()[0];

Class<?> c = Class.forName(ste.getClassName());
String mname = ste.getMethodName();

// NOTE:
// Exceptions thrown in constructors have a method name of "<init>"
// Exceptions thrown in static initialization blocks have a method name of
//    "<cinit>"

if ("<init>".equals(mname)) {
    // Constructors are the possible "methods", all of these:
    c.getConstructors();
} else if ("<cinit>".equals(mname)) {
    System.out.println("Thrown in a static initialization block!");
} else {
    // Thrown from a method:
    for (Method m : c.getMethods()) {
        if (m.getName().equals(mname)) {
            System.out.println("Possible method: " + m);
        }
    }
}

Upvotes: 4

afzalex
afzalex

Reputation: 8652

Use StackTrace() for this.

public class Test {

    protected void toFail(String someparameter) throws Exception {
        throw new Exception();
    }

    public static void main(String[] args) {
        try {
            new Test().toFail("");
        }catch(Exception ex){
            StackTraceElement[] stl = ex.getStackTrace();
            System.out.println(stl[0].getMethodName());
       }
    }
}

Upvotes: 0

Related Questions