Jetez un oeil à cette question étrange:valeur du champ Inexpliqué changement
- J'ai un point d'arrêt sur tous les accès au champ
res1
- Res1 reçoit la valeur de f, qui est "bar"
- est maintenant Res1 "bar"
- Lors de la prochaine pause, RES1 est soudainement
null
Pourquoi est-ce impossible?
- En raison du point d'arrêt sur RES1, je peux voir qu'il ne devrait pas avoir changé du tout
- Et il ne pouvait pas, parce que je ne change pas explicitement entre l'affectation et le
assertEquals
et ce le code s'exécute dans un seul thread JUnit. Il n'y a pas d'autres champs ou variables nommésres1
.
Quoi de neuf? Je suppose que ce n'est pas un bug dans la JVM, mais qui sait. Comme Jon Skeet l'a dit, le problème est que les instances sont différentes. Cela est dû à cette question étrange de réflexion:
public class ServiceObject {
private static final Map<Class<?>, Map<String, Operation>> opsByClass =
new ConcurrentHashMap<Class<?>, Map<String,Operation>>();
private final Object target;
private final Map<String, Operation> myClassOps;
private class Operation {
private final Method method;
public Operation(Method met) {
this.method = met;
method.setAccessible(true);
}
public void execute(Map<String,?> args, Responder responder, Object context, boolean coerce) {
...
method.invoke(target, mArgs);
}
}
public ServiceObject(Object target) {
Class<?> myClass = target.getClass();
Map<String, Operation> op = opsByClass.get(myClass);
if (op == null) {
op = new HashMap<String, Operation>();
for (Method meth : myClass.getMethods()) {
...
op.put(opName, new Operation(meth));
}
opsByClass.put(myClass, op);
}
this.target = target;
this.myClassOps = op;
}
public void execute(String opName) {
Operation op = myClassOps.get(opName);
...
op.execute(args, responder, context, coerce);
}
}
// Foo is equivalent to the class that contains <res1> above
class Foo {
@ServiceOperation
public void bar() {
// breakpoint here
}
}
Que se passe lorsque les tests sont exécutés:
a = new Foo();
b = new Foo();
svc = new ServiceObject(a);
svc.execute("bar", ...); // inside Foo.bar() <this> will be <a>
svc = new ServiceObject(b);
svc.execute("bar", ...); // inside Foo.bar() <this> will still be <a>, but should be <b>
Pourriez-vous également écrire du code? –
Pouvez-vous le réduire à la quantité minimale de code nécessaire pour démontrer le problème et afficher le code dans son intégralité? – NPE
@aix: Code affiché –