如何从Java中的静态方法调用getClass()?

时间:2011-11-26 00:50:21

标签: java static-methods

我有一个必须有一些静态方法的类。在这些静态方法中,我需要调用方法getClass()来进行以下调用:

public static void startMusic() {
  URL songPath = getClass().getClassLoader().getResource("background.midi");
}

然而Eclipse告诉我:

Cannot make a static reference to the non-static method getClass() 
from the type Object

修复此编译时错误的适当方法是什么?

10 个答案:

答案 0 :(得分:546)

只需使用TheClassName.class代替getClass()

答案 1 :(得分:104)

对于问题中的代码示例,标准解决方案是通过名称明确引用类,甚至可以不进行getClassLoader()调用:

class MyClass {
  public static void startMusic() {
    URL songPath = MyClass.class.getResource("background.midi");
  }
}

这种方法仍然有一个背面,即如果您需要将此代码复制到许多类似的类,它对复制/粘贴错误不是很安全。

至于标题中的确切问题,adjacent thread中有一个技巧:

Class currentClass = new Object() { }.getClass().getEnclosingClass();

它使用嵌套的匿名Object子类来获取执行上下文。这个技巧有复制/粘贴安全的好处......

在其他类继承的基类中使用它时要小心:

值得注意的是,如果此片段被形成为某个基类的静态方法,那么currentClass值将始终是对该基类的引用,而不是对可能正在使用该方法的任何子类的引用。

答案 2 :(得分:56)

在Java7 +中,您可以在静态方法/字段中执行此操作:

MethodHandles.lookup().lookupClass()

答案 3 :(得分:18)

我自己也在努力解决这个问题。一个很好的技巧是使用当前线程在静态上下文中获取ClassLoader。这也适用于Hadoop MapReduce。其他方法在本地运行时有效,但在MapReduce中使用时返回null InputStream。

public static InputStream getResource(String resource) throws Exception {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   InputStream is = cl.getResourceAsStream(resource);
   return is;
}

答案 4 :(得分:13)

只需使用一个类文字,即NameOfClass.class

答案 5 :(得分:9)

getClass()方法在Object类中定义,具有以下签名:

  

public final Class getClass()

由于它未定义为static,因此无法在静态代码块中调用它。有关详细信息,请参阅以下答案:Q1Q2Q3

如果你处于静态上下文中,那么你必须使用类文字表达式来获取类,所以你基本上必须这样做:

  

让Foo.class

这种类型的表达式称为类文字,它们在Java Language Specification Book中解释如下:

  

类文字是一个表达式,由类,接口,数组或基本类型的名称组成,后跟一个“。”和令牌类。类文字的类型是Class。它计算为由当前实例的类的定义类加载器定义的命名类型(或void)的Class对象。

您还可以在API documentation上找到有关此主题的信息。

答案 6 :(得分:5)

试试吧

Thread.currentThread().getStackTrace()[1].getClassName()

或者

Thread.currentThread().getStackTrace()[2].getClassName()

答案 7 :(得分:0)

假设有一个Utility类,则示例代码为-

    URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));

CustomLocation-如果资源中有任何文件夹结构,则删除此字符串文字。

答案 8 :(得分:0)

我有同样的问题! 但是要解决此问题,只需按以下步骤修改您的代码即可。

FROM adoptopenjdk/openjdk11:centos-slim

RUN yum install maven-3.6.3

CMD [""]

这对我来说效果很好,希望对您也一样。

答案 9 :(得分:-2)

尝试这样的事情。这个对我有用。 Logg(班级名称)

    String level= "";

    Properties prop = new Properties();

    InputStream in =
            Logg.class.getResourceAsStream("resources\\config");

    if (in != null) {
        prop.load(in);
    } else {
        throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
    }

    level = prop.getProperty("Level");