10
votes

Reflets illégalargumentexception causes

mise à jour strong> - pour rendre la question plus claire.

Quelle est la cause possible d'obtenir une clastingexception ClasscastException tout en appelant une méthode via des réflexions? p>

J'ai eu la stacktrace suivante comme une partie de ma candidature tout en essayant d'invoquer une méthode via des réflexions. p>

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;
        }

    }
}


2 commentaires

Les dernières modifications que vous avez apportées à votre code ont éliminé l'exception qui a été lancée. Dites-vous que vous obtenez toujours des erreurs même avec ce nouveau SSCCE? Sinon, veuillez revenir au code précédent qui illustre réellement le problème que vous rencontrez.


L'erreur provient de mon code d'application, qui est très élaboré et je ne peux pas poster ici. Ceci est mon (échec) tente de recréer l'erreur ou de comprendre pourquoi il arrive ..


3 Réponses :


1
votes

Eh bien, c'est le problème:

reflections.invokeMethod("doLong", 1L);


8 commentaires

Ce n'est pas mon code d'application. J'essaie de recréer l'exception classique, alors j'appelle volontairement une réflexion.Invokemethod ("DOINT", 1L); L'erreur qu'elle jette ici est l'inactivité de type argument, pas une exception classique


@gap_j: ah, je vois. Ce n'était pas à tout clair avant. Quelle est la fermeture est ce code à votre code d'application réel (dans la partie réflexion)?


Il y a 2 différences entre cela et mon code d'application. 1) La méthode appelle dans ma demande n'a aucun argument. 2) Il pourrait être invoqué sur une classe de proxy. J'essaie de recréer en utilisant ces deux cas, toujours infructueux


@gap_j: Si vous invoquez une méthode sans argument, je ne peux pas voir que le code de l'exemple que vous avez fourni est utile du tout - c'est clairement peut être un problème de conversion d'argument s'il y a n'y a pas d'arguments! Cela semble beaucoup plus probable que la différence de classe de proxy est l'importance importante. Il est vraiment important qu'une question donne autant de contexte que possible: les deux points auraient dû être dans la question du début.


Je n'ai pas posté le code entier car je pensais que ce sera un peu trop pour poster 2 classes et 1 interface ici. J'ai posté la petite partie pour donner un certain contexte, je mettrai à jour la question et ajouterai l'échantillon complet s'il aide.


J'ai mis à jour la question et ajouté le code maintenant. J'espère que ça aide.


@gap_j: Eh bien, vous avez mis à jour le code, qui est bon - mais ce n'est toujours pas clair ce que vous sont obtenez vs ce que vous Attendez-vous. Si vous êtes vraiment intéressé par la classecastException, il ne sert à rien d'avoir des méthodes avec des arguments. (Et il n'y a définitivement aucun point dans l'inclusion des commentaires non-Javadoc.) Fondamentalement, vous devez couper le code pour être court, complet et toujours représentatif de la situation que vous voulez que nous comprenions.


Je ne m'intéresse que dans la classecastException, mais je pensais que ce serait utile énumérer les cas pour sauver les autres le temps. Mais je suppose que ce que vous dites est juste, j'ai supprimé le code qui pourrait ne pas être la cause. Et merci pour les conseils!



0
votes

J'ai un peu modifier votre code pour reproduire cette erreur: xxx pré>

voici l'interface p> xxx pré>

Ajouter la méthode en classe Réflexions et entitéInvocacitéHandler afin de compiler. Ajoutez ensuite cette méthode dans votre principale (). Exécuter et je produis le temps d'exécution d'erreur. P>

invokeMethod(reflectionsProxy, "doSomething1", "1");


1 commentaires

Mon message de code d'origine avait 2 méthodes similaires et l'exception que vous obtenez. Mais dans mon cas, la méthode des exceptions de la méthode n'a aucun argument, j'ai modifié l'exemple pour refléter cela. Je ne suis intéressé que dans les raisons de la catégorie ClasscastException si je suis en mesure de recréer les autres cas. (Voir la réponse de Jon Skeet et les commentaires)



16
votes

J'avais recréée ClassCastException code> par modifing votre code exemple:. Invoke invokeMethod code> avec un argument correct 10000 fois, puis invoquez avec mal un mal d'un

le principale méthode code> dans le Réflexions code> p>

java.lang.IllegalArgumentException: java.lang.ClassCastException@603a3e21
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.twbbs.pccprogram.Reflections.invokeMethod(Reflections.java:33)
    at org.twbbs.pccprogram.Reflections.main(Reflections.java:16)


9 commentaires

C'est assez intéressant, je vais essayer cela, mais la méthode que j'essaie d'invoquer n'a aucun argument! Une idée de l'exception pourrait-elle venir dans une méthode d'argumentation zéro?


@gap_j j'avais édité ma réponse pour jeter l'exception dans une méthode d'argumentation zéro.


L'erreur est recréée dans votre ancien cas, avec des arguments. Mais avec la modification (méthode de l'argument zéro), sa ne pas être recréée.


Il a recréé sur mon ordinateur! Laissez-moi vérifier ce que j'oublie de poster. Euh ... probablement vous n'avez probablement pas roulé refletsInterface et DOSOMODIQUE Retour à votre version d'exemple d'origine Version du code?


Je l'ai à l'ancienne version. et passer un nouvel objet à invokemethod ne fera rien car il ne trouvera pas une méthode avec un nom correspondant. Êtes-vous sûr que c'est le code exact que vous utilisez? Pourriez-vous poster le code exact ici? Pouvez-vous également spécifier la version Java que vous utilisez.


@gap_j Vous devez être modifier à la fois principal et invokemethod .


GG John. J'ai aussi cherché un peu sur ce problème et je ne pouvais pas comprendre comment obtenir cette exception. Thx pour la question et la réponse. +1 pour votre réponse;)


Quelqu'un peut-il expliquer pourquoi illégalargumentexception est jeté pour un appel à une méthode qui ne prend pas d'arguments?


Existe-t-il un moyen de désactiver cette optimisation?