getClass()和静态方法:什么是最佳实践?

时间:2009-03-02 05:54:19

标签: java reflection static

我希望通过反思给将要使用我的代码的程序员提供一些便利。为了实现我想要的结果,我想获得扩展我的代码的类的类对象。即使他们无法覆盖我希望从中访问信息的静态方法,它也会有用。我可能最终只是为了避免这种情况而重构设计,但是想把这个问题抛给社区。

我所知道的实现这一目标的唯一方法是获取当前线程,导航堆栈跟踪,并提取类名,然后将其转换为类的实际实例。

还有其他建议吗?

旁注:上述方法也是我了解获取调用方法的唯一方法。

4 个答案:

答案 0 :(得分:2)

不幸的是,走堆栈并不一定安全:

来自JDK 6 Javadoc for getStackTrace:

  

某些虚拟机可能在某些情况下   情况,省略一个或多个堆栈   堆栈跟踪中的帧。在里面   极端情况下,虚拟机   没有堆栈跟踪信息   关于这个扔掉是允许的   返回一个零长度数组   这种方法。一般来说,   这个方法返回的数组会   每帧包含一个元素   这将由印刷   的printStackTrace。

您也许可以使用调试器api来完成它。我相信调试的东西能够全速使用HotSpot(我可能是错的)所以你不会看到这样做的巨大速度。您可以先看一下:http://java.sun.com/javase/6/docs/technotes/guides/jpda/trace.html

此外,建立在未答复的答案......

class Base
{
    // instance method helper
    public final int foo()
    {
        return (foo(this.getClass()));
    }

    // the real helper, with access to the class
    private static int foo(final Class clazz)
    {
        return (0);
    }
}

class Child
    extends Base
{
    public void bar()
    {
        final int x;

        x = foo();
    }
}

答案 1 :(得分:1)

在静态方法中,从你的扩展中获得的某个(任何)类是什么保证在堆栈中?

如果你仔细想一想,我怀疑你会意识到你所寻找的东西是不存在的。

/编辑1 / 我认为你需要的是

abstract class B {
    <T extends B> B create(Class<T> clazz) {
    ....
}

嗯。如果createprotected方法怎么办?然后,您可以非常确定来电者是B,如果调用者无法分配给UnsupportedOperation,您甚至可以要求IllegalStateB

您可以使用Thread.currentThread().getStackTrace()

答案 2 :(得分:1)

创建Throwable非常昂贵,所以如果经常调用你的方法(例如,每秒超过一次),请不要使用它 稍微好一点的方法是Thread.currentThread()。getStackTrace()。

如果使用Sun的JVM,另一种方法是Reflection.getCallerClass(n)。这要快得多,但不能移植到其他JVM。如果你担心这个问题,你可以使用另一种方法,如果它可用则调用它,如果没有则使用堆栈跟踪。

所有这些假设您的静态方法不公开。如果所有赌注都已关闭,因为任何类都可以调用您的方法,而不仅仅是扩展您的方法。

答案 3 :(得分:0)

我建议避免反思的泥潭。你似乎正在做一些简单的编程。使用简单的实现(没有足够的信息来合理猜测可能是什么)。

相关问题