Vous aimez ce que vous lisez sur ce blog ?
Envie d'aller plus loin avec véritable formation d'expertise en Java ?
Venez suivre ma formation Masterclasse Expertise Java !

"Même un développeur experimenté a besoin de continuer à apprendre. Et dans cette formation... j'ai appris beaucoup !" - A.G., Java Champion

Sessions intra-entreprises sur demande : contact[at]mokatech.net.
Inscrivez-vous vite !

Java Quiz #39

If you're not getting your athletic body's tanned on a beach this week, here is a small quiz to keep your brain fit.
What does this code snippet do ?

  1. public class Quiz39 {
  2.  
  3. public static void main(String[] args) {
  4. int[] array = null;
  5. try {
  6. array[0] = array[(array = createArray())[array.length - 1]];
  7. } finally {
  8. System.out.println("Array = " + Arrays.toString(array));
  9. }
  10. }
  11.  
  12. public static int[] createArray() {
  13. return new int[]{1, 2, 3, 4};
  14. }
  15.  
  16. }

Answer :

This code raises a NullPointerException (NPA) but... still initializes the int array !

Array = [1, 2, 3, 4]
Exception in thread "main" java.lang.NullPointerException
	at net.thecodersbreakfast.quiz.quiz39.Quiz39.main(Quiz39.java:11)
	at (...)

The key to understanding this surprising behavior is given (as often) in the Java Language Specification JLS, §15.13 :

If the array reference expression produces null instead of a reference to an array, then a NullPointerException is thrown at run time, but only after all parts of the array access expression have been evaluated and only if these evaluations completed normally.

In our quiz, the left-hand expression "array0" raises the NPE as expected, but only after the right-hand expression is fully evaluated ; and the fact that this right-hand expression could effectively eliminate the NPE problem (by assigning a non-null reference to the array local variable) is not taken into account...

This quiz show clearly one of the rare cases of delayed exception raising in Java.


Commentaires

1. Le dimanche 20 juin 2010, 17:30 par Scamp

Petit indice, il faut lire les spécifications du langage Java (alias jls)
http://java.sun.com/docs/books/jls/...

2. Le dimanche 20 juin 2010, 18:07 par judu

Ça plantouille, non ? (tentative d'accès à array4 il me semble)

3. Le dimanche 20 juin 2010, 18:13 par Jérôme

Hum, sympa ce quiz... Alors, essayons voir :

1/ array est initialisé à null (ligne 4)
2/ ligne 6, la référence à array à droite du = est évaluée. Elle vaut null.
3/ le contenu du premier crochet à droite du = est évalué :

3a/ appel à createArray puis assignation à array de {1,2,3,4}
3b/ la référence (array = createArray()) est évaluée à {1,2,3,4}
3c/ le contenu de [array.length - 1] est évalué à [3]
3d/ notre premier crochet à droite du = est finalement évalué à {1,2,3,4}[3] soit 4

4/ on évalue donc (résultat de 2/)[résultat de 3/] soit null [4] => NullPointerException
5/ le bloc finally est appelé, il imprime la valeur de array, qui vaut {1,2,3,4}depuis 3a/

J'espère que je n'ai rien manqué...

4. Le mardi 22 juin 2010, 13:06 par ABO

l'idée est de découper :
au lieu de lire :
array0 = array(array = createArray())[array.lengt...];
On lira :
array = createArray();
int i = arrayarray.length - 1;
array0 = arrayi;

la dernière ligne levra une exception :
java.lang.ArrayIndexOutOfBoundsException parceque i=4

5. Le vendredi 25 juin 2010, 08:04 par duto

En fait expression array(array = createArray())[array.lengt...] peut être découpé en 2 expressions :

- aarray.length - 1
- array = createArray()

mais elles sont exécutés dans l'ordre suivant :
d'abord aarray.length - 1 puis array = createArray() donc on a un java.lang.ArrayIndexOutOfBoundsException car array est à null.

6. Le vendredi 25 juin 2010, 08:47 par duto

c'est peut-être plutôt un NullPointerException ^^

7. Le vendredi 25 juin 2010, 16:00 par Benoit BESNARD

Moi je dirais aussi NullPointerException en tenant compte de l'ordre d'exécution de la ligne.
Mais sinon, si le tableau est créé avant, i est bien égal à 4.

8. Le mardi 29 juin 2010, 09:43 par Brice

Je suis plus d'accord avec Jerôme

array[0] = array[(array = createArray())[array.length - 1]];

                    î
                  null [4]; => NPE

Mais je n'aurais pas parié dessus si je n'avais pas lu cette section de la spec du langage!

9. Le mardi 6 juillet 2010, 17:15 par louis gueye

on l'attend toujours cette réponse !

Ajouter un commentaire

Le code HTML est affiché comme du texte et les adresses web sont automatiquement transformées.