[java] How to call getClass() from a static method in Java?

I have a class that must have some static methods. Inside these static methods I need to call the method getClass() to make the following call:

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

However Eclipse tells me:

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

What is the appropriate way to fix this compile time error?

This question is related to java static-methods

The answer is


Suppose there is a Utility class, then sample code would be -

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

CustomLocation - if any folder structure within resources otherwise remove this string literal.


As for the code example in the question, the standard solution is to reference the class explicitly by its name, and it is even possible to do without getClassLoader() call:

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

This approach still has a back side that it is not very safe against copy/paste errors in case you need to replicate this code to a number of similar classes.

And as for the exact question in the headline, there is a trick posted in the adjacent thread:

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

It uses a nested anonymous Object subclass to get hold of the execution context. This trick has a benefit of being copy/paste safe...

Caution when using this in a Base Class that other classes inherit from:

It is also worth noting that if this snippet is shaped as a static method of some base class then currentClass value will always be a reference to that base class rather than to any subclass that may be using that method.


In Java7+ you can do this in static methods/fields:

MethodHandles.lookup().lookupClass()

Try something like this. It works for me. Logg (Class name)

    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");

I wrestled with this myself. A nice trick is to use use the current thread to get a ClassLoader when in a static context. This will work in a Hadoop MapReduce as well. Other methods work when running locally, but return a null InputStream when used in a MapReduce.

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

Simply use a class literal, i.e. NameOfClass.class


Try it

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

Or

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

getClass() method is defined in Object class with the following signature:

public final Class getClass()

Since it is not defined as static, you can not call it within a static code block. See these answers for more information: Q1, Q2, Q3.

If you're in a static context, then you have to use the class literal expression to get the Class, so you basically have to do like:

Foo.class

This type of expression is called Class Literals and they are explained in Java Language Specification Book as follows:

A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.

You can also find information about this subject on API documentation for Class.


I had the same problem ! but to solve it just modify your code as following.

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

this worked fine with me hope it will also work fine with you.