Java 获取对象实例的源类

Java 获取对象实例的源类,java,class,extends,Java,Class,Extends,我的Java应用程序需要序列化/反序列化通过HTTP接收的XML结构。此XML消息几乎在任何XML级别上都可能包含错误元素。这就是为什么所有类都扩展apirerror。请参阅以下问题: 我创建了以下类: public class ApiError { private String code; private String level; private String text; public get/set...() {} } 我的应用程序中几乎所有其他类都扩展了apirer

我的Java应用程序需要序列化/反序列化通过HTTP接收的XML结构。此XML消息几乎在任何XML级别上都可能包含错误元素。这就是为什么所有类都扩展
apirerror
。请参阅以下问题:

我创建了以下类:

public class ApiError {
  private String code;
  private String level;
  private String text;

  public get/set...() {}

}
我的应用程序中几乎所有其他类都扩展了
apirerror
类,因为这些类可能会引发错误

我希望有一个类似于
getErrorOrigin()
的方法,它返回首先创建
apierro
实例的类的名称

Java中有没有一种简单的方法来实现这一点

谢谢,

Robert

如果您的意思是想要包含使用
new
运算符的代码的类的名称,那么请在APIRERROR
对象发起人
中声明一个字段,将Object类型的参数添加到APIRROR构造函数中,并在创建代码过程
中声明此
。然后可以使用
originator.getClass().getName()
。如果您是从静态块或静态方法创建其中一个,则必须进行punt操作。

如果您的意思是想要包含使用
new
运算符的代码的类的名称,则必须在apierro
Object originator
中声明一个字段,将Object类型的参数添加到apierro构造函数中,并在创建代码过程中
。然后可以使用
originator.getClass().getName()
。如果要从静态块或静态方法创建其中一个线程,则必须进行punt操作。

是的,您可以通过在
apierro
构造函数中获取当前线程的堆栈跟踪来执行此操作:

public ApiError() {
    StackTraceElement[] trace = Thread.currentThread().getStackTrace();
    this.errorOrigin = trace[2].getClassName();
}
你可以通过放置

Thread.dumpStack();
apirerror
构造函数中。如果您创建一个新的
apierro
实例,您将看到一个堆栈跟踪,如下所示:

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)
java.lang.Exception:堆栈跟踪
位于java.lang.Thread.dumpStack(Thread.java:1249)
错误时。(Test.java:39)
at Test.main(Test.java:9)
Thread.currentThread().getStackTrace()
将为您提供一个
StackTraceeElement
对象数组:

  • 该数组的第一个元素将用于
    getStackTrace()
    方法本身,该方法在生成跟踪时执行
  • 第二个元素是
    apirerror
    构造函数,它调用
    getStackTrace()
  • 第三个元素——您想要的元素(因此索引
    2
    )——用于调用
    apierro
    构造函数的方法。通过在该元素上调用
    getClassName()
    ,可以获得包含调用
    apierro
    构造函数的方法的类的名称

说到这里,您似乎正在尝试重新实现异常。我会认真考虑从方法中抛出异常,而不是返回<代码> APIOrror < /Cord>对象。这使得错误处理与“业务逻辑”分离。此外,错误(希望)是一种异常情况,因此使用异常进行错误处理是有意义的,而不是让
ApiError
污染您的类层次结构。

是的,您可以通过在
ApiError
构造函数中获取当前线程的堆栈跟踪来做到这一点:

public ApiError() {
    StackTraceElement[] trace = Thread.currentThread().getStackTrace();
    this.errorOrigin = trace[2].getClassName();
}
你可以通过放置

Thread.dumpStack();
apirerror
构造函数中。如果您创建一个新的
apierro
实例,您将看到一个堆栈跟踪,如下所示:

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)
java.lang.Exception:堆栈跟踪
位于java.lang.Thread.dumpStack(Thread.java:1249)
错误时。(Test.java:39)
at Test.main(Test.java:9)
Thread.currentThread().getStackTrace()
将为您提供一个
StackTraceeElement
对象数组:

  • 该数组的第一个元素将用于
    getStackTrace()
    方法本身,该方法在生成跟踪时执行
  • 第二个元素是
    apirerror
    构造函数,它调用
    getStackTrace()
  • 第三个元素——您想要的元素(因此索引
    2
    )——用于调用
    apierro
    构造函数的方法。通过在该元素上调用
    getClassName()
    ,可以获得包含调用
    apierro
    构造函数的方法的类的名称

说到这里,您似乎正在尝试重新实现异常。我会认真考虑从方法中抛出异常,而不是返回<代码> APIOrror < /Cord>对象。这使得错误处理与“业务逻辑”分离。此外,错误(希望)是一种异常情况,因此使用异常进行错误处理是有意义的,而不是让
ApiError
污染您的类层次结构。

所有类都扩展一个。。。好主意。无论如何,只是一个提示:看看
Thread.getStackTrace()
是否对您有用

所有类扩展一个。。。好主意。无论如何,只是一个提示:看看
Thread.getStackTrace()
是否对您有用

如果您抛出异常而不吞咽堆栈跟踪,它将告诉您发起者。您应该让
apirerror
扩展
java.lang.Exception
,这样您就可以访问堆栈跟踪,我想这将解决您的问题。否则(丑陋)您可能会在
apierro
的构造函数中有一个参数,它是一个
类,由创建错误的对象定义(例如
new apierro(this.getClass())
。然后您可以在需要时输出此类名。[编辑:这是下面Ted Hopp的解决方案。]这不是对您当前问题的回答,但您可能希望重新考虑您的设计:我怀疑每个类都与
apierro
类有扩展关系:它看起来更像
apierro
是一个您所有人都可以使用的接口