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

Java getClass()和静态方法:最佳实践是什么?,java,reflection,static,Java,Reflection,Static,我希望通过反思为将使用我的代码的程序员提供一些便利。为了达到我想要的结果,我想为扩展代码的类获取class对象。即使它们不能覆盖我希望从中访问信息的静态方法,但它目前会很有帮助。为了避免这种情况,我可能会简单地重构一下设计,但我想把这个问题抛给社区 我知道实现这一点的唯一方法是获取当前线程,导航堆栈跟踪,提取类名,然后将其转换为类的实际实例 还有其他建议吗 旁注:上述方法也是我知道的获取调用方法的唯一方法。在静态方法中,如何保证从您的方法扩展的任何类都在堆栈上 如果你想一想,我怀疑你会意识到你所

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

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

还有其他建议吗


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

在静态方法中,如何保证从您的方法扩展的任何类都在堆栈上

如果你想一想,我怀疑你会意识到你所寻找的并不存在

/编辑1/ 我想你需要的是

abstract class B {
    <T extends B> B create(Class<T> clazz) {
    ....
}
嗯,如果create是受保护的方法呢?然后,您可以非常确定调用方是B,您甚至可以要求,如果调用方不可分配给B,则抛出UnsupportedOperation或IllegalState


在静态方法中,可以使用Thread.currentThread.getStackTrace

,如何保证从您的类扩展的任何类都在堆栈上

如果你想一想,我怀疑你会意识到你所寻找的并不存在

/编辑1/ 我想你需要的是

abstract class B {
    <T extends B> B create(Class<T> clazz) {
    ....
}
嗯,如果create是受保护的方法呢?然后,您可以非常确定调用方是B,您甚至可以要求,如果调用方不可分配给B,则抛出UnsupportedOperation或IllegalState


您可以使用Thread.currentThread.getStackTrace

遍历堆栈不一定安全:

从用于getStackTrace的JDK 6 Javadoc:

在某些情况下,某些虚拟机可能 在这种情况下,省略一个或多个堆栈 来自堆栈跟踪的帧。在 极端情况下,虚拟机 没有堆栈跟踪信息 关于这一点,我们是允许的 从中返回零长度数组的步骤 这个方法。一般来说 此方法返回的数组将 每个帧包含一个元素 这将由 printStackTrace

您也许可以使用调试器api来完成这项工作。我相信调试工具能够全速使用HotSpot,我可能是错的,所以你不会看到这样做会带来巨大的速度冲击。您可以从以下内容开始:

此外,基于未回答的答案

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();
    }
}

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

从用于getStackTrace的JDK 6 Javadoc:

在某些情况下,某些虚拟机可能 在这种情况下,省略一个或多个堆栈 来自堆栈跟踪的帧。在 极端情况下,虚拟机 没有堆栈跟踪信息 关于这一点,我们是允许的 从中返回零长度数组的步骤 这个方法。一般来说 此方法返回的数组将 每个帧包含一个元素 这将由 printStackTrace

您也许可以使用调试器api来完成这项工作。我相信调试工具能够全速使用HotSpot,我可能是错的,所以你不会看到这样做会带来巨大的速度冲击。您可以从以下内容开始:

此外,基于未回答的答案

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();
    }
}

我建议避免陷入沉思的泥潭。您似乎正在进行某种简单的编程。使用一个简单的实现,因为没有足够的信息来合理地猜测可能是什么。

我建议避免陷入反射的泥潭。您似乎正在进行某种简单的编程。使用一个简单的实现,因为没有足够的信息来合理地猜测可能是什么。

创建一个可丢弃的是非常昂贵的,所以如果你的方法经常被调用,不要使用这个方法。每秒不止一次 更好的方法是Thread.currentThread.getStackTrace

如果您使用Sun的JVM,另一种方法是Reflection.getCallerClassn。这要快得多,但不能移植到其他JVM。如果您关心这个问题,您可以使用另一个方法,如果它可用,则调用它,如果不可用,则使用堆栈跟踪


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

创建一个可丢弃的是非常昂贵的,所以如果你的方法经常被调用,不要使用这个方法。每秒不止一次 更好的方法是Thread.currentThread.getStackTrace

如果您使用Sun的JVM,另一种方法是Reflection.getCallerClassn。这要快得多,但不能移植到其他JVM。如果你担心的话 关于这一点,您可以使用另一个方法,如果该方法可用,则调用它,如果不可用,则使用堆栈跟踪


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

这是我真正害怕的。在我所做的工作中,静态方法返回它们所表示的类的实例,并以基于反射的自动连接为支持。我想我将采用重构的方法,使用一个中心工厂类来接受一个类以及原始请求。哦,但是静态方法只表示声明它们的类。您将需要一个类实例。请参见上面/编辑1/中的示例,这是我真正害怕的。在我所做的工作中,静态方法返回它们所表示的类的实例,并以基于反射的自动连接为支持。我想我将采用重构的方法,使用一个中心工厂类来接受一个类以及原始请求。哦,但是静态方法只表示声明它们的类。您将需要一个类实例。请参见上面/EDIT 1/中的我的示例您可以作为StackTraceElements遍历堆栈-没有必要或建议严格解析printStackTrace打印的字符串。您可以作为StackTraceElements遍历堆栈-没有必要或建议严格解析printStackTrace打印的字符串。我正在使用Java ORM附带项目。部分目标是一些非java配置,没有xml模式定义,java b中的迁移,编译时没有代码生成,为了以抽象的方式实现这些目标,反射提供了大量语法支持。我正在开发一个java ORM,作为一个小型的辅助项目。部分目标是一点非java配置,没有xml模式定义,java b中的迁移,编译时没有代码生成,为了以抽象的方式实现这些目标,反射提供了大量语法。