J'ai une classe qui doit avoir des méthodes statiques. À l'intérieur de ces méthodes statiques, j'ai besoin d'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
Quelle est la manière appropriée de corriger cette erreur de temps de compilation?
java
static-methods
Rama
la source
la source
getResource()
avant qu'il y ait une instance d'une classe définie par l'utilisateur (par exemple non J2SE) échouera parfois. Le problème est que le JRE utilisera le chargeur de classe de démarrage à ce stade, qui n'aura pas de ressources d'application sur le chemin de classe (du chargeur de démarrage).Réponses:
La réponse
Utilisez simplement
TheClassName.class
au lieu degetClass()
.Déclaration des enregistreurs
Étant donné que cela attire tellement l'attention sur un cas d'utilisation spécifique - pour fournir un moyen facile d'insérer des déclarations de journal - j'ai pensé ajouter mes réflexions à ce sujet. Les frameworks de journaux s'attendent souvent à ce que le journal soit contraint à un certain contexte, par exemple un nom de classe complet. Ils ne sont donc pas copiables-collables sans modification. Des suggestions de déclarations de journaux à coller sont fournies dans d'autres réponses, mais elles présentent des inconvénients tels que le gonflement du bytecode ou l'ajout d'une introspection d'exécution. Je ne les recommande pas. Le copier-coller est un éditeur préoccupation de l' , donc une solution d'édition est la plus appropriée.
Dans IntelliJ, je recommande d'ajouter un modèle en direct:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
comme modèle de texte.className()
Maintenant, si vous tapez,
log<tab>
il se développera automatiquementEt reformatez et optimisez automatiquement les importations pour vous.
la source
Log
dans Android, qui nécessite la fourniture d'une balise, généralement le nom de la classe. Et il y a probablement d'autres exemples. Bien sûr, vous pouvez déclarer un champ pour cela (ce qui est une pratique courante), mais c'est toujours copier-coller.CLASS
taperclassName()
. Cela garantira que $ CLASS $ est réellement remplacé par le nom de la classe, sinon il sortira simplement vide.Quant à l'exemple de code dans la question, la solution standard est de référencer explicitement la classe par son nom, et il est même possible de se passer d'
getClassLoader()
appels:Cette approche a toujours un côté arrière 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 quant à la question exacte dans le titre, il y a une astuce publiée dans le fil adjacent :
Il utilise une
Object
sous-classe anonyme imbriquée pour saisir le contexte d'exécution. Cette astuce a l'avantage d'être sûre copier / coller ...Attention lors de l'utilisation dans une classe de base dont les autres classes héritent:
Il convient également de noter que si cet extrait est façonné comme une méthode statique d'une classe de base, la
currentClass
valeur sera toujours une référence à cette classe de base plutôt qu'à toute sous-classe qui peut utiliser cette méthode.la source
Class.getResource()
peut se comporter légèrement différemment deClassLoader.getResource()
; voir stackoverflow.com/a/676273Dans Java7 +, vous pouvez le faire dans des méthodes / champs statiques:
la source
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
J'ai lutté avec ça moi-même. Une bonne astuce consiste à utiliser le thread actuel pour obtenir un ClassLoader dans un contexte statique. Cela fonctionnera également dans un MapReduce Hadoop. D'autres méthodes fonctionnent lors de l'exécution locale, mais retournent un InputStream nul lorsqu'il est utilisé dans un MapReduce.
la source
Utilisez simplement un littéral de classe, c.-à-d.
NameOfClass.class
la source
getClass()
est définie dans la classe Object avec la signature suivante: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 , Q3 .Si vous êtes dans un contexte statique, vous devez utiliser l'expression littérale de classe pour obtenir la classe, vous devez donc essentiellement faire comme:
Ce type d'expression est appelé Class Literals et ils sont expliqués dans le Java Language Specification Book comme suit:
Vous pouvez également trouver des informations sur ce sujet dans la documentation de l'API pour Class.
la source
Essayez-le
Ou
la source
[1]
, tous les messages de journal seront signalésThread
comme source sur Android 4.4.4.[2]
semble donner le résultat correct sur Android et OpenJRE.Supposons qu'il existe une classe Utility, alors l'exemple de code serait -
CustomLocation - si une structure de dossiers dans les ressources, sinon supprimez ce littéral de chaîne.
la source
Essayez quelque chose comme ça. Ça marche pour moi. Logg (nom de classe)
la source