Raison de l'exception java.lang.Exception verifyerror: Mauvais type sur des opérandes de pile
Ci-dessous simple code java envoie l'
java.lang.Exception verifyerror: Mauvais type sur des opérandes de pile exception
public class TestJavaCodes {
int parentData = 0;
public void init() {
A ob = new B();
}
public static void main(String[] args) {
TestJavaCodes testJavaCodes = new TestJavaCodes();
testJavaCodes.init();
}
public static class A {
public A(MyLambdaFunc lambdaFunc) {
}
}
public class B extends A {
public B() {
super((data1, type) -> {
parentData = 1;
});
}
}
@FunctionalInterface
public static interface MyLambdaFunc {
public void onData(String data, int type);
}
}
Si je supprime le code
parentData = 1
de B
'constructeur, l'exception ne viendra pas.
Peut on dire la raison pour cela?
OriginalL'auteur dGayand | 2015-05-21
Vous devez vous connecter pour publier un commentaire.
Le problème se pose parce que votre expression lambda ne fait pas référence à
this
ou un membre dethis
mais un membre de la extérieurthis
. Aviez-vous écrit la classeB
commele compilateur l'a rejetée sans aucun doute que l'accès à
innerData
implique l'accèsthis
.Le point sur l'extérieur de l'instance, c'est qu'il est une constante qui est même disponible lorsque l'instance intérieure n'a pas été entièrement construit encore. Il est donc correct d'accepter le code, mais malheureusement, le compilateur génère du code qui tente d'accéder à l'extérieur de l'instance par l'intermédiaire d'un implicite champ de l'intérieur de la classe, instance, et donc l'expression lambda requiert une instance de l'intérieur de la classe et d'essayer d'utiliser la pas entièrement construit à l'intérieur de la classe de l'instance de produit l'erreur.
Il peut être facilement démontré que le code peut être compilé correctement:
avec cette petite modification, la lambda expression fait référence à l'extérieur de l'instance, sans accéder à l'instance intérieure et aucune erreur ne survient.
public static class A { public A(int x) {} } public class B extends A { public B() { super(parentData = 1); } }
. Donc, même explicite de changement de l'extérieur de la classe est autorisé avant l'appel de la super-classe. Semble que CJCE compilateur a un bogue trop.Merci pour l'explication,
OriginalL'auteur Holger
Semble que ce code ne devrait pas compiler. Je minimisé votre code:
Il est compilé sans problème par javac 1.8.0.25, 1.8.0.40 et 1.9b57. Chaque version compilée produit le même résultat lors du lancement:
Ce code n'est pas compilé par la CJCE du compilateur. Il signale une erreur de compilation:
De sorte qu'il ressemble à un bug du compilateur javac: elle doit retourner une erreur de compilation à la place (comme CJCE).
Je n'ai pas trouver de bug similaire dans OpenJDK bug tracker, donc soumis un nouveau rapport de bug via le formulaire en ligne. Si Java les gens sont à la lecture de ce, la révision interne ID affecté est JI-9021379.
Mise à jour: Le rapport de bug est accepté (JDK-8129740)
Khambata: “Beaucoup mieux” à ce sujet? La déclaration de “ce code ne devrait pas compiler à tous” est tout simplement faux et le lien bug rapport reconnaît que la CJCE comportement de rejeter le code est erroné. Et à partir de Java 8, mise à jour 121,
javac
compile ce code à une classe valide fichier qui s'exécute sans erreur.OriginalL'auteur Tagir Valeev