J'ai une classe qui doit avoir des méthodes statiques. Dans ces méthodes statiques, je dois appeler la méthode getClass () pour effectuer l'appel suivant:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
Cependant Eclipse me dit:
Cannot make a static reference to the non-static method getClass()
from the type Object
Quel est le moyen approprié pour corriger cette erreur de temps de compilation?
Utilisez simplement TheClassName.class
au lieu de getClass()
.
En ce qui concerne l'exemple de code dans la question, la solution standard consiste à référencer explicitement la classe par son nom, et il est même possible de se passer de getClassLoader()
call:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
Cette approche a toujours un verso qui n’est pas très sûr contre les erreurs de copier/coller au cas où vous auriez besoin de répliquer ce code dans un certain nombre de classes similaires.
Et comme pour la question exacte dans le titre, il y a une astuce publiée dans le fil de discussion adjacent :
Class currentClass = new Object() { }.getClass().getEnclosingClass();
Il utilise une sous-classe Object
anonyme anonyme pour obtenir le contexte d'exécution. Cette astuce a l'avantage d'être sans danger pour le copier/coller ...
Attention lorsque vous utilisez ceci dans une classe de base dont d'autres classes héritent:
Il convient également de noter que si cet extrait a la forme d'une méthode statique d'une classe de base, la valeur currentClass
sera toujours une référence à cette classe de base plutôt qu'à toute sous-classe susceptible d'utiliser cette méthode.
En Java7 +, vous pouvez le faire dans des méthodes/champs statiques:
MethodHandles.lookup().lookupClass()
J'ai lutté avec cela moi-même. Une bonne astuce consiste à utiliser le thread actuel pour obtenir un ClassLoader dans un contexte statique. Cela fonctionnera également dans un Hadoop MapReduce. D'autres méthodes fonctionnent lors de l'exécution locale, mais renvoient un InputStream nul lorsqu'elles sont utilisées dans un MapReduce.
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
Utilisez simplement un littéral de classe, c'est-à-dire NameOfClass.class
La méthode getClass()
est définie dans la classe d'objets avec la signature suivante:
public final Classe getClass ()
Comme il n'est pas défini comme static
, vous ne pouvez pas l'appeler dans un bloc de code statique. Voir ces réponses pour plus d'informations: Q1 , Q2 , Q .
Si vous êtes dans un contexte statique, vous devez utiliser l'expression littérale de classe pour obtenir la classe. Vous devez donc procéder comme suit:
Foo.class
Ce type d'expression s'appelle Les littéraux de classe . Ils sont expliqués de la manière suivante dans livret de spécification du langage Java , comme suit:
Un littéral de classe est une expression constituée du nom d'une classe, d'une interface, d'un tableau ou d'un type primitif suivi d'un `. ' et la classe de jeton. Le type d'un littéral de classe est Class. Il renvoie l'objet Class pour le type nommé (ou pour void) tel que défini par le chargeur de classes définissant la classe de l'instance actuelle.
Vous pouvez également trouver des informations à ce sujet sur documentation API pour Class.
L'essayer
Thread.currentThread().getStackTrace()[1].getClassName()
Ou
Thread.currentThread().getStackTrace()[2].getClassName()