Get origin class of object instance
My Java application needs to serialize/deserialize an XML structure received via HTTP. This XML message may contain an Error element on almost any level of the XML. That's why all classes extend ApiError
. Please see the following question as well: Deserialize repeating XML elements in Simple 2.5.3 (Java)
I have created the following class:
public class ApiError {
private String code;
private String level;
private String text;
public get/set...() {}
}
Almost every other class in my application extends the ApiError
class as those classes may raise an error.
I'd like to have a method like getErrorOrigin()
which returns the name of the class which fir开发者_StackOverflow中文版st created an instance of ApiError
?
Is there an easy way in Java how to do this?
Thanks,
RobertYes, you can do this, by getting the stack trace of the current thread in the ApiError
constructor:
public ApiError() {
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
this.errorOrigin = trace[2].getClassName();
}
You can see why this works by putting
Thread.dumpStack();
in the ApiError
constructor. If you create a new instance of ApiError
, you'll see a stack trace that looks like this:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1249)
at ApiError.<init>(Test.java:39)
at Test.main(Test.java:9)
Thread.currentThread().getStackTrace()
will give you an array of StackTraceElement
objects:
- The first element of that array will be for the
getStackTrace()
method itself, which is executing when the trace is generated. - The 2nd element will be the
ApiError
constructor, which calledgetStackTrace()
. - The 3rd element - the one you want (hence the index
2
) - is for the method that called theApiError
constructor. By callinggetClassName()
on that element, you get the name of the class containing the method that invoked theApiError
constructor.
Having said all that, it seems you're trying to reimplement exceptions. I would seriously consider throwing exceptions from your methods, rather than returning ApiError
objects. This keeps the error handling separate from your 'business logic'. Also errors are (hopefully) an exceptional situation, so it makes sense to use exceptions for error handling, rather than having ApiError
pollute your class hierarchy.
all classes extend one ... Very bad idea. Anyway, just a hint: see if Thread.getStackTrace()
is useful for you ...
If you mean that you want the name of the class containing the code that used the new
operator, then declare a field in ApiError Object originator
, add an argument of type Object to the ApiError constructor, and in the creating code pass this
. Then you can use originator.getClass().getName()
. You'll have to punt if you are creating one of these from a static block or static method.
精彩评论