getClass() 和静态方法:最佳实践是什么?
-
03-07-2019 - |
题
我希望通过反射为将使用我的代码的程序员提供一些便利。为了实现我想要的结果,我想获取扩展我的代码的类的类对象。尽管它们无法覆盖我希望从中访问信息的静态方法,但它目前会很有帮助。我最终可能会简单地重构一下设计来避免这种情况,但想把这个问题扔给社区。
据我所知,实现此目的的唯一方法是获取当前线程,导航堆栈跟踪并提取类名,然后将其转换为该类的实际实例。
还有其他建议吗?
边注:上述方法也是我知道获取调用方法的唯一方法。
解决方案
在静态方法中时,如何保证从您的类扩展的某些(任何)类位于堆栈上?
如果您稍微考虑一下,我怀疑您会意识到您正在寻找的东西并不存在。
/编辑1/我认为您需要什么
abstract class B {
<T extends B> B create(Class<T> clazz) {
....
}
嗯。如果什么 create
是 protected
方法?那么你就可以非常确定来电者是 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。如果您担心这一点,您可以使用另一种方法,如果可用则调用此方法,如果不可用则使用堆栈跟踪。
所有这些都假设您的静态方法不是公共的。如果是这样,那么所有的赌注都消失了,因为你的方法可以被任何类调用,而不仅仅是一个扩展你的方法的类。
我建议避免陷入反思的泥潭。您似乎正在做某种简单的编程。使用简单的实现(没有足够的信息来合理猜测它可能是什么)。