我希望通过反射为将使用我的代码的程序员提供一些便利。为了实现我想要的结果,我想获取扩展我的代码的类的类对象。尽管它们无法覆盖我希望从中访问信息的静态方法,但它目前会很有帮助。我最终可能会简单地重构一下设计来避免这种情况,但想把这个问题扔给社区。

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

还有其他建议吗?

边注:上述方法也是我知道获取调用方法的唯一方法。

有帮助吗?

解决方案

在静态方法中时,如何保证从您的类扩展的某些(任何)类位于堆栈上?

如果您稍微考虑一下,我怀疑您会意识到您正在寻找的东西并不存在。

/编辑1/我认为您需要什么

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

嗯。如果什么 createprotected 方法?那么你就可以非常确定来电者是 B, ,你甚至可以要求这样做,抛出 UnsupportedOperation 或者 IllegalState 如果调用者不可分配给 B.

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

其他提示

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

来自 getStackTrace 的 JDK 6 Javadoc:

某些虚拟机可能在某些 情况,省略一个或多个堆栈 堆栈跟踪中的帧。在 极端情况下,虚拟机 没有堆栈跟踪信息 关于这个投掷是允许的 返回一个长度为零的数组 这种方法。一般来说, 此方法返回的数组将 每帧包含一个元素 将由 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();
    }
}

创建 Throwable 非常昂贵,因此如果您的方法经常被调用(例如每秒不止一次) 稍微好一点的方法是 Thread.currentThread().getStackTrace()。

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

所有这些都假设您的静态方法不是公共的。如果是这样,那么所有的赌注都消失了,因为你的方法可以被任何类调用,而不仅仅是一个扩展你的方法的类。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top