如何在不使用类名的情况下在静态方法中获取Class对象?

时间:2013-01-17 12:26:30

标签: java class inheritance reflection static

我有

public class A {
    static X s_x = new X(A.class);
}

public class B {
    static X s_x = new X(B.class);
}
对于许多没有任何特殊关系或共性的课程,

等等。我真正希望我能做的是在超类中初始化s_x,但是使用特定于子类的代码;这是不可能的,因为静态代码不可覆盖。所以,我想至少让我的复制粘贴更容易。我想要一个魔术表达式,它计算出Class对象,即写:

    static X s_x = new X(/* magic expression here */);

其中魔术表达式是相同的,无论我在哪个类中声明我的X,但是与上面的示例相同。第二个最佳选择是静态方法,以达到同样的效果。

注意:

  • Java 6尽可能。
  • 这个问题不是(必然)关于记录......

8 个答案:

答案 0 :(得分:1)

我曾经有过这个奇怪的要求,我试图搜索但没有找到任何东西,所以我猜答案是不可能的。

但我被告知要重新考虑我的方法,当我尝试时,我找出了相同的解决方案,没有这个奇怪的要求。所以请重新考虑你的方法。我相信你能像我一样解决它。此外,如果您可以发布您尝试解决的问题/方案,我可以提供帮助。

答案 1 :(得分:1)

在Java 7中,您可以使用类java.lang.invoke.MethodHandles

Class c = MethodHandle.lookup().lookupClass()

您可能会收到有关使用原始类型而不是参数化版本Class<X>的警告,但我无法看到您如何避免这种情况,而无需自行重新编写类名称。

答案 2 :(得分:1)

在HotSpot / OpenJDK中,您可以使用

 Class c = Reflection.getCallerClass(1)

注意:这是一个内部API,可能无法在所有JVM上运行。

答案 3 :(得分:1)

这是一个应该在Java 5+ JVM中运行的单行程序,并且不会在代码中添加任何其他导入:

new Object(){}.getClass().getEnclosingClass()

它创建一个匿名内部类,获取其Class对象,然后获取其封闭的类实例,该实例应该是您的类。例如:

public class HelloClass {
    static final Class<?> THIS_CLASS = new Object(){}.getClass().getEnclosingClass();

    public static void main(String[] args) {
        System.out.println(THIS_CLASS); // prints "class HelloClass"
    }
}

在您的问题中:

static X s_x = new X(new Object(){}.getClass().getEnclosingClass());

答案 4 :(得分:0)

我认为唯一的解决方案是从当前的堆栈跟踪中提取类名称(请参阅Thread.getStackTrace()),它将以String的形式提供给您,您可以从中获取{使用Class的{​​1}}对象,但这比您当前的方法更加丑陋。

答案 5 :(得分:0)

您可以这样做,但需要对您的方法进行一些重新分解:

试试这个:

class X
{

   public X(String cName)
   {
     try
     {
       Class.forName(cName);
      }catch(ClassNotFoundException cne)
       {}
   }
}

public class Test
{
    static X x1 = new X(Thread.currentThread().getStackTrace()[1].getClassName());
}

答案 6 :(得分:0)

如果要创建日志记录对象,可以使用lombok为您注入日志记录对象。 页面示例:

@Log
public class LogExample {

  public static void main(String... args) {
    log.error("Something's wrong here");
  }
}

答案 7 :(得分:0)

这里的一些答案有一个解决方案的想法,但不是我需要的代码片段。所以这就是,在任何JVM上工作:

static X s_x = new X(getClassStatic());

public static Class<?> getClassStatic() {
    try {
        // we're using the third highest stack element, since the
        // first highest is the getStackTrace() method, followed by this method itself. We
        // want the calling code's class.
        String name = Thread.currentThread().getStackTrace()[2].getClassName();
        return Class.forName(name);
    } catch (ClassNotFoundException e) {
        // shouldn't be able to get here...
        return null;
    }
}

或者,对于选定的JVM,根据Peter Lawrey的建议:

static X s_x = new X(getCallerClass(1));