J’essaye de déboguer une application Java basée sur la réflexion. Pour le moment, j’obtiens l’erreur suivante:

java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:146)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:150)
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.getInt(UnsafeIntegerFieldAccessorImpl.java:38)
at sun.reflect.UnsafeIntegerFieldAccessorImpl.get(UnsafeIntegerFieldAccessorImpl.java:18)
at java.lang.reflect.Field.get(Field.java:358)

Les dernières lignes de l’application en cours d’exécution sont:

Field f = classUnderTest.getDeclaredField(processFieldName(var));
f.setAccessible(true);
Long value = (Long) f.get(runtimeInstance);

Le message d’erreur est un peu trompeur et je ne sais pas pourquoi il mentionne un set Chirurgie pendant que j’essaie d’en faire une get.

Je soupçonne que runtimeInstance n’est pas un objet de la classe attendue. Mais ce message d’erreur me jette.

Quelqu’un a-t-il déjà rencontré ce problème? Des indices?

PS1: La ligne exacte à l’origine de l’exception est la suivante:

Long value = (Long) f.get(runtimeInstance);

PS2: processFieldName(var) traite le nom correct du champ, c’est-à-dire que certains artefacts sont supprimés d’une chaîne avec le nom du champ comme this. etc.

Réponse 1:

La source de ces accesseurs indique que la classe déclarant le champ n’est pas assignable par le runtimeInstanceClasser:

if (! (this.field.getDeclaringClass (). isAssignableFrom (paramObject.getClass ())) throwSetIllegalArgumentException (paramObject);

field semble être le champ que vous souhaitez obtenir de l’instance, paramObject est ton runtimeInstance.

Donc, si la classe déclarante du champ n’est pas la classe ou une superclasse du paramObject, vous obtiendrez ce message.

Chaque chance à vous paramObject est un Integer Ici?

Edit: Voici un code source d’OpenJDK (devrait être similaire à celui d’Oracle) pour expliquer le message:

protected String getSetMessage(String attemptedType, String attemptedValue) {
String err = "Can not set";
if (Modifier.isStatic(field.getModifiers()))
err += " static";
if (isFinal)
err += " final";
err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";
if (attemptedValue.length() > 0) {
err += "(" + attemptedType + ")" + attemptedValue;
} else {
if (attemptedType.length() > 0)
err += attemptedType;
else
err += "null value";
}
return err;
}

Prenez votre message java.lang.IllegalArgumentException: Can not set int field DataStructures.StackAr.topOfStack to java.lang.Integer Nous pensons que:

  • Le champ est de type int
  • Le nom du champ est topOfStack en classe DataStructures.StackAr
  • attemptedType est java.lang.Integer

Depuis attemptedType est le genre de vôtre runtimeInstance Je suppose classUnderTest est DataStructures.StackAr tandis que runtimeInstance est du type java.lang.Integer.

Réponse 2:

La source Java de l’erreur que vous obtenez en haut de la pile semble suggérer que runtimeInstance n’est pas la même classe que classUnderTest:

protected void ensureObj(Object o) {
// NOTE: will throw NullPointerException, as specified, if o is null
if (!field.getDeclaringClass().isAssignableFrom(o.getClass())) {
throwSetIllegalArgumentException(o);
}
}

Réponse 3:

Lisez attentivement le message d’erreur: « Le champ int DataStructures.StackAr.topOfStack ne peut pas être défini sur java.lang. Entier « 

Tu dois changer ça Integer à un int avant de l’attribuer.



Source link

Recent Posts