Le suivant compile très bien dans mon Eclipse:
final int j = 1/0;
// compiles fine!!!
// throws ArithmeticException: / by zero at run-time
Java empêche beaucoup de "dumb code" même à partir de la compilation en premier lieu (par exemple, "Five" instanceof Number
ne compile pas!), donc, le fait n'en est pas de même de générer autant qu'un avertissement a été très surprenant pour moi. L'intrigue s'intensifie lorsque vous considérez le fait que des expressions constantes sont autorisés à être optimisé au moment de la compilation:
public class Div0 {
public static void main(String[] args) {
final int i = 2+3;
final int j = 1/0;
final int k = 9/2;
}
}
Compilé dans Eclipse, l'extrait ci-dessus génère les éléments suivants du code binaire (javap -c Div0
)
Compiled from "Div0.java"
public class Div0 extends java.lang.Object{
public Div0();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1 // "i = 5;"
2: iconst_1
3: iconst_0
4: idiv
5: istore_2 // "j = 1/0;"
6: iconst_4
7: istore_3 // "k = 4;"
8: return
}
Comme vous pouvez le voir, l' i
et k
affectations sont optimisés comme des constantes de compilation, mais la division en 0
(qui doit avoir été détectable au moment de la compilation) est tout simplement compilés à l'est.
javac 1.6.0_17
se comporte encore plus étrangement, la compilation en mode silencieux mais d'exciser les affectations à l' i
et k
complètement hors du bytecode (probablement parce qu'il a déterminé qu'ils ne sont pas utilisés n'importe où) mais en laissant de l' 1/0
intact (depuis la suppression il serait la cause d'un programme totalement différent de la sémantique).
Donc les questions sont:
- Est -
1/0
la loi l'expression de Java qui devrait compiler n'importe quand n'importe où?- Ce n'JLS dire à ce sujet?
- Si c'est légal, est-il une bonne raison pour cela?
- À quoi bon, cela pourrait-il servir?