Je veux obtenir la classe d’appel de la méthode, c.-à-d.
class foo{ bar(); }
Dans la barre de méthodes, je dois obtenir le nom de classe foo
, et j’ai trouvé cette méthode:
Class clazz = sun.reflect.Reflection.getCallerClass(1);
Cependant, même si getCallerClass
est public
, lorsque j’essaie de l’appeler, Eclipse dit:
Ressortingction d’access: La méthode getCallerClass () du type Reflection n’est pas accessible en raison des ressortingctions sur la bibliothèque requirejse C: \ Program Files \ Java \ jre7 \ lib \ rt.jar
- Quelle fonction de hachage Java utilise-t-elle pour implémenter la classe Hashtable?
- Comment répertorier tous les objects AWS S3 dans un compartiment à l’aide de Java
- Éclipse et accolades
- importer NotNull ou Nullable et Android Studio ne comstackra pas
- Comment créer une interface entre Fragment et l’adaptateur?
Y a-t-il d’autres choix?
Vous pouvez générer une trace de stack et utiliser les informations dans StackTraceElements .
Par exemple, une classe d’utilitaires peut vous renvoyer le nom de la classe appelante:
public class KDebug { public static Ssortingng getCallerClassName() { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); for (int i=1; i
Si vous appelez KDebug.getCallerClassName()
partir de bar()
, vous obtiendrez "foo"
.
En supposant que vous souhaitiez connaître la classe de la bar
appel de méthode (ce qui est plus intéressant et peut-être ce que vous vouliez vraiment). Vous pouvez utiliser cette méthode:
public static Ssortingng getCallerCallerClassName() { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); Ssortingng callerClassName = null; for (int i=1; i
Est-ce pour le débogage? Sinon, il pourrait y avoir une meilleure solution à votre problème.
Pour que le nom de classe de l’appelant ou de l’appelé soit utilisé sous le code, cela fonctionne très bien pour moi.
Ssortingng callerClassName = new Exception().getStackTrace()[1].getClassName(); Ssortingng calleeClassName = new Exception().getStackTrace()[0].getClassName();
Cela dépend fortement de ce que vous recherchez … Mais cela devrait avoir la classe et la méthode qui ont appelé cette méthode directement dans cet object.
Pour le nom de classe / méthode / fichier:
Thread.currentThread().getStackTrace()[2].getClassName(); Thread.currentThread().getStackTrace()[2].getMethodName(); Thread.currentThread().getStackTrace()[2].getFileName();
Pour la classe:
Class.forName(Thread.currentThread().getStackTrace()[2].getClassName())
FYI: Class.forName () lève une ClassNotFoundException qui n’est pas runtime. Vous aurez besoin d’essayer attraper.
De plus, si vous cherchez à ignorer les appels dans la classe elle-même, vous devez append une boucle avec la logique pour vérifier cette chose particulière.
Quelque chose comme … (je n’ai pas testé ce morceau de code alors méfiez-vous)
StackTraceElement[] stes = Thread.currentThread().getStackTrace(); for(int i=2;i
Juste une pensée....
SecurityManager
a une méthode protégée getClassContext
En créant une classe d’utilitaires qui étend SecurityManager, vous pouvez y accéder.
public class CallingClass extends SecurityManager { public static final CallingClass INSTANCE = new CallingClass(); public Class[] getCallingClasses() { return getClassContext(); } }
Utilisez CallingClass.INSTANCE.getCallingClasses()
pour récupérer les classes appelantes.
Il y a aussi une petite bibliothèque (avertissement: le mien) WhoCalled qui expose ces informations. Il utilise Reflection.getCallerClass lorsqu’il est disponible, sinon retourne à SecurityManager.
Je sais que c’est une vieille question mais je pensais que le demandeur voulait la classe, pas le nom de la classe. J’ai écrit une petite méthode pour obtenir la classe réelle. C’est une sorte de sortingche et peut ne pas toujours fonctionner, mais parfois, quand vous avez besoin de la classe actuelle, vous devrez utiliser cette méthode …
/** * Get the caller class. * @param level The level of the caller class. * For example: If you are calling this class inside a method and you want to get the caller class of that method, * you would use level 2. If you want the caller of that class, you would use level 3. * * Usually level 2 is the one you want. * @return The caller class. * @throws ClassNotFoundException We failed to find the caller class. */ public static Class getCallerClass(int level) throws ClassNotFoundException { StackTraceElement[] stElements = Thread.currentThread().getStackTrace(); Ssortingng rawFQN = stElements[level+1].toSsortingng().split("\\(")[0]; return Class.forName(rawFQN.subssortingng(0, rawFQN.lastIndexOf('.'))); }
C’est le moyen le plus efficace d’obtenir uniquement la classe des appelants. D’autres approches prennent un vidage de stack complet et ne vous donnent que le nom de la classe.
Cependant, cette classe est sous le sun.*
Qui est vraiment à usage interne. Cela signifie qu’il peut ne pas fonctionner sur d’autres plates-formes Java ou même sur d’autres versions de Java. Vous devez décider si c’est un problème ou non.
Le message d’erreur rencontré par l’OP est simplement une fonctionnalité Eclipse. Si vous souhaitez associer votre code à un fabricant spécifique (et même à une version) de la machine sun.reflect.Reflection.getCallerClass()
, vous pouvez utiliser efficacement la méthode sun.reflect.Reflection.getCallerClass()
. Vous pouvez ensuite comstackr le code en dehors d’Eclipse ou le configurer pour ne pas considérer ce diagnostic comme une erreur.
La configuration Eclipse la plus mauvaise consiste à désactiver toutes les occurrences de l’erreur en:
Project Properties
/ Java Comstackr
/ Errors/Warnings
/ Enable project specific settings
définis sur Deprecated and ressortingted API
/ Deprecated and ressortingted API
/ Forbidden reference (access rules)
définies sur Warning
ou Ignore
.
La meilleure configuration d’Eclipse consiste à désactiver une occurrence spécifique de l’erreur en:
Project Properties
/ Java Build Path
/ Libraries
/ JRE System Library
/ Access rules:
sélectionnez / Edit...
/ Add...
/ Resolution:
définissez sur Discouraged
ou Accessible
/ Rule Pattern
défini sur sun/reflect/Reflection
.
J’utilise la méthode suivante pour obtenir l’appelant pour une classe spécifique de la stacktrace:
package test.log; public class CallerClassTest { public static void main(final Ssortingng[] args) { final Caller caller = new Caller(new Callee()); caller.execute(); } private static class Caller { private final Callee c; public Caller(final Callee c) { this.c = c; } void execute() { c.call(); } } static class Callee { void call() { System.out.println(getCallerClassName(this.getClass())); } } /** * Searches the current threads stacktrace for the class that called the given class. Returns {@code null} if the * calling class could not be found. * * @param clazz * the class that has been called * * @return the caller that called the class or {@code null} */ public static Ssortingng getCallerClassName(final Class> clazz) { final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final Ssortingng className = clazz.getName(); boolean classFound = false; for (int i = 1; i < stackTrace.length; i++) { final StackTraceElement element = stackTrace[i]; final String callerClassName = element.getClassName(); // check if class name is the requested class if (callerClassName.equals(className)) classFound = true; else if (classFound) return callerClassName; } return null; } }
Puisque j’ai actuellement le même problème, voici ce que je fais:
Je préfère com.sun.Reflection au lieu de stackTrace car une trace de stack ne produit que le nom et non la classe (y compris le chargeur de classes) lui-même.
La méthode est obsolète mais toujours disponible dans Java 8 SDK.
// descripteur de méthode # 124 (I) Ljava / lang / Class; (obsolète) // Signature: (I) Ljava / lang / Class <*>; @ java.lang.Deprecated public statique natif java.lang.Class getCallerClass (int arg0);
// descripteur de méthode # 122 () Ljava / lang / Class; // Signature: () Ljava / lang / Class <*>; @ sun.reflect.CallerSensitive public statique natif java.lang.Class getCallerClass ();
Comme je dois être bla bla indépendant de la plate-forme, y compris les ressortingctions de sécurité, je crée simplement une méthode flexible:
Vérifiez si com.sun.Reflection est disponible (les exceptions de sécurité désactivent ce mécanisme)
Si 1 est oui, alors obtenez la méthode avec un argument int ou no int.
Si 2 est oui, appelez-le.
Si 3. n’a jamais été atteint, j’utilise la trace de la stack pour renvoyer le nom. J’utilise un object de résultat spécial qui contient la classe ou la chaîne et cet object indique exactement ce que c’est et pourquoi.
[Summary] J’utilise stacktrace pour la sauvegarde et pour contourner les avertissements du compilateur éclipse j’utilise des reflections. Fonctionne très bien Garder le code propre, fonctionne comme un charme et indique également les problèmes impliqués correctement.
Je l’utilise depuis assez longtemps et aujourd’hui j’ai cherché une question connexe pour
Vous trouverez ci-dessous un exemple simple illustrant comment obtenir des noms de classe et de méthode.
public static void main(Ssortingng args[]) { callMe(); } void callMe() { try { throw new Exception("Who called me?"); } catch( Exception e ) { System.out.println( "I was called by " + e.getStackTrace()[1].getClassName() + "." + e.getStackTrace()[1].getMethodName() + "()!" ); } }
e a getClassName()
, getFileName()
, getLineNumber()
et getMethodName()
…