Jak wywołać getClass () ze statycznej metody w Javie?

Mam klasę, która musi mieć jakieś statyczne metody. Wewnątrz tych statycznych metod muszę wywołać metodę getClass () aby wykonać następujące wywołanie:

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

Jednak Eclipse mówi mi:

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

Jaki jest odpowiedni sposób, aby naprawić ten błąd czasu kompilacji?

Author: Eric Leschinski, 2011-11-26

8 answers

Po prostu użyj TheClassName.class zamiast getClass().

 491
Author: Mark Peters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-26 00:51:50

Jeśli chodzi o przykład kodu w pytaniu, standardowym rozwiązaniem jest odwołanie się do klasy bezpośrednio po jej nazwie, a nawet możliwe jest obejście się bez wywołania getClassLoader():

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

To podejście nadal ma tylną stronę, że nie jest bardzo bezpieczne przed błędami kopiowania / wklejania w przypadku, gdy trzeba replikować ten kod do wielu podobnych klas.

A co do dokładnego pytania w nagłówku, to w sąsiednim wątku jest trick:

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

Używa zagnieżdżona podklasa anonymous Object, aby uchwycić kontekst wykonania. Ta sztuczka ma tę zaletę, że jest bezpieczna dla kopiowania/wklejania...

Uwaga Podczas używania tego w klasie bazowej, z której dziedziczą inne klasy:

Warto również zauważyć, że jeśli ten fragment jest ukształtowany jako statyczna metoda jakiejś klasy bazowej, to currentClass wartość zawsze będzie odniesieniem do tej klasy bazowej, a nie do jakiejkolwiek podklasy, która może używać tej metody.

 98
Author: Sergey Ushakov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-27 17:52:07

W Java7+ możesz to zrobić w statycznych metodach / polach:

MethodHandles.lookup().lookupClass()
 50
Author: Rein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-06 18:34:10

Sam się z tym zmagałem. Fajną sztuczką jest użycie bieżącego wątku, aby uzyskać ClassLoader w kontekście statycznym. Będzie to działać również w Hadoop MapReduce. Inne metody działają, gdy działają lokalnie, ale zwracają strumień null, gdy są używane w MapReduce.

public static InputStream getResource(String resource) throws Exception {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   InputStream is = cl.getResourceAsStream(resource);
   return is;
}
 16
Author: starkadder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-14 18:45:49

Po prostu Użyj klasy literalnej, tzn. NameOfClass.class

 13
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-26 00:52:42

getClass() metoda jest zdefiniowana w klasie obiektu o następującej sygnaturze:

Public final Class getClass ()

Ponieważ nie jest zdefiniowany jako static, nie można go wywołać w statycznym bloku kodu. Zobacz te odpowiedzi, aby uzyskać więcej informacji: Q1, Q2, Q3 .

Jeśli jesteś w kontekście statycznym, musisz użyć dosłownego wyrażenia klasy, aby uzyskać klasę, więc zasadniczo musisz zrobić tak:

Foo.klasa

Ten typ wyrażenia nazywa się literałami klasy i są one wyjaśnione w książce specyfikacji języka Java w następujący sposób:

Literał klasy jest wyrażeniem składającym się z nazwy klasy, interfejsu, tablicy lub typu prymitywnego, po którym następuje `. i klasy tokena. Typem klasy literalnej jest klasa. Wartościuje do obiektu klasy dla nazwanego typu (lub dla void) zdefiniowanego przez definiującą klasę loader klasy obecna instancja.

Informacje na ten temat można również znaleźć w dokumentacji API dla klasy.

 9
Author: melihcelik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:32

Try it

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

Lub

Thread.currentThread().getStackTrace()[2].getClassName()
 5
Author: Ishfaq,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-21 07:53:34

Spróbuj czegoś takiego. Dla mnie działa. Logg (Nazwa klasy)

    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");
 -2
Author: Oliver Lagerbäck Westblom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 14:26:22