Réflexions IllegalArgumentException causes
Mise à JOUR - de faire De la question plus claire.
Quelle est la cause possible d'obtenir une ClassCastException en appelant une méthode via réflexions?
J'ai eu la suivante stacktrace comme une partie de mon application, tout en essayant d'invoquer une méthode via réflexions.
java.lang.IllegalArgumentException: java.lang.ClassCastException@21fea1fv
at sun.reflect.GeneratedMethodAccessor332.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.....
(remaining is my method stack trace)
J'ai essayé un exemple de classe et adopté plusieurs arguments de types différents, mais je reçois toujours un cette exception.
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Mise à JOUR -
Voici un exemple de code que j'ai écrit pour essayer de recréer l'exception
Interface pour créer de la classe proxy
package my.tests;
public interface ReflectionsInterface {
public abstract void doSomething();
}
C'est la classe de test
package my.tests;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Reflections implements ReflectionsInterface {
public static void main(String[] args) {
Reflections reflections = new Reflections();
ReflectionsInterface reflectionsProxy = reflections.createProxy(ReflectionsInterface.class);
invokeMethod(reflectionsProxy, "doSomething", null);
}
public <T> T createProxy(Class<T> entityInterface) {
EntityInvocationHandler eih = new EntityInvocationHandler(this);
T cast = entityInterface.cast(Proxy.newProxyInstance(
entityInterface.getClassLoader(), new Class[]{entityInterface}, eih));
return cast;
}
public static void invokeMethod(Object obj, String methodName, Object... args) {
Method[] methods = obj.getClass().getMethods();
try {
for (Method method : methods) {
if (method.getName().equals(methodName)) {
method.invoke(obj, args);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void doSomething() {
System.out.println("woo");
}
private final static class EntityInvocationHandler implements InvocationHandler,
ReflectionsInterface {
private Reflections reflectionObj;
public EntityInvocationHandler(Reflections reflectionObj) {
super();
this.reflectionObj = reflectionObj;
}
@Override
public void doSomething() {
reflectionObj.doSomething();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(this, args);
return invoke;
}
}
}
Je suis incapable de comprendre la où je reçois argument de l'incompatibilité de type et la ClassCastException serait causé.
Je ne suis pas en mesure de re-créer l'exception et voudrais savoir pourquoi il vient. Tout travail code re-créé, ou une source de la référence au code de jeter cette exception dans ce cas sera bon
Je suis passé par la Method.class la documentation javadoc et le code source, je ne suis pas en mesure de comprendre pourquoi cette erreur vient.
L'erreur vient de mon code de l'application, ce qui est très élaborée et je ne peux pas poster ici. C'est mon essai (raté) de re-créer l'erreur ou à comprendre pourquoi il est à venir..
OriginalL'auteur gap_j | 2013-04-16
Vous devez vous connecter pour publier un commentaire.
J'avais recréé le
ClassCastException
en modifiant votre code d'exemple: InvoquerinvokeMethod
avec un bon argument 10000 fois, et puis l'invoquer à mal un mal un.La
main
méthode dans leReflections
classeLa
invokeMethod
méthode dans leReflections
classeTrace De La Pile:
Mon explication de la
ClassCastException
:Lorsque vous appelez
invokeMethod
pour la première fois, la JVM de l'utilisation d'un ralentissement de la route, ce qui est plus facile pour les développeurs de déboguer (donc c'est plus lent!), donc, il va afficher un plus sympathiqueargument type mismatch
message lorsque vous passe un mauvais argument.Lorsque vous appelez
invokeMethod
pour un grand nombre de fois (16 fois sont assez dans mes tests), la JVM généré unGeneratedMethodAccessor***
dans l'exécution, qui est plus rapide, avec moins de contrôle d'erreur. Donc, il va montrer une telle laideurjava.lang.ClassCastException@603a3e21
message lorsque vous passe un mauvais argument.Vous avez besoin d'être modifier à la fois
main
etinvokeMethod
.oh oui, mon mauvais. Cela a fonctionné! Merci beaucoup! Brillant trucs!
gg John. J'ai cherché un peu sur ce problème et je ne pouvais pas comprendre comment profiter de cette exception. Merci pour la question et la réponse. +1 pour ta réponse 😉
Quelqu'un peut m'expliquer pourquoi IllegalArgumentException est jeté pour un appel à une méthode qui ne prend aucun argument?
OriginalL'auteur johnchen902
C'est bien le problème:
Vous appelez
doInt
, mais vous êtes de passage unlong
valeur. Si la réflexion est en train de jeter unLong
à unInteger
, ce qui n'est pas valide.Je soupçonne que vous avez voulu dire:
Ah, je vois. Ce n'était pas à tous effacer avant. Comment fermer est ce code à votre code réel de l'application (dans le reflet de la partie)?
Il y a 2 différences entre le présent et mon code d'application. 1) la méthode invoquée dans mon application n'a pas d'arguments. 2) Il peut être invoquée sur une classe proxy. Je suis en train de recréer à l'aide de ces deux cas, ne fonctionne pas non plus
Si vous êtes en invoquant une méthode sans argument, je ne vois pas que l'exemple de code fourni est utile à tous - clairement ne peut pas être un argument de conversion de problème si il n'y a pas d'arguments! Il semble beaucoup plus probable que le proxy différence de classe est le plus important. Il est vraiment important qu'une question donne contexte autant que possible: ces deux points ont été dans la question depuis le début.
je n'ai pas poster tout le code que j'ai pensé que ça va être un peu trop de post à 2 classes et 1 interface ici. J'ai posté la une petite partie à donner un peu de contexte, je mettrai à jour la question et ajouter la totalité de l'échantillon si ça aide.
OriginalL'auteur Jon Skeet
J'ai un peu modifier votre code pour reproduire cette erreur :
Voici l'interface
Ajouter une méthode dans la classe de Réflexions et de EntityInvocationHandler afin de compiler. Ajoutez ensuite cette méthode dans votre main(). Exécuter et j'produire l'erreur d'exécution.
J'ai essayé d'obtenir de l'onu ClassCastException mais je n'ai pas réussi.
Il se produit probablement dans votre code original parce qu'il y a plus d'objets et d'un type non valide est passé à la méthode. Ajouter journaux et essayez de déboguer pour isoler le ClassCastException.
OriginalL'auteur mki