Les inner class (question de certification OCJP)

Si vous avez contemplé passer la certification OCJP (anciennement SCJP) vous avez certainement rencontré des questions test qui vous ont fait réflêchir. Un exemple est le code ci-dessous dont on demande la sortie.

class MyClass
{
    public static void main (String[] args)
    {
        String s = "whizlab";
        System.out.println(s);
    }
   
    public class String
    {      
        public String(String s)
        {
            System.out.println("simulator");
        }
    }
}

What is the output?

A. whizlab simulator
B. whizlab
C. Compilation error
D. None of the above

Si on pose cette question c’est sans doute pour voir si un programmeur est familier avec la manière dont java exécute le code.

Faisons un rapide survol du « snippet » au dessus:
- On a une class personalisée MyClass.
- Une méthode static void main qui sera enclenchée lors d’un run.
- Un inner class du nom String avec un seul constructeur acceptant un String. Il ne fait pas d’extends sur le String standard donc pas de soucis vis-à-vis du fait que celui-ci est final.

Si vous avez executé le code par curiosité (par exemple sur http://ideone.com/) vous aurez sans doute constaté qu’une erreur est produite, la réponse étant donc le C.

Mais la question est de savoir pourquoi. Imaginez que vous êtes un interpréteur ou un compilateur. Vous rencontrez une référence à une nom de class String.

Une règle dit ici que le premier endroit où on va chercher une classe est dans le scope local. Donc au niveau de la classe elle même où l’on trouve notre inner class String. Et c’est en suivant ce cheminement que vous rendez certainement compte d’où provient l’erreur.

La première ligne du main fait référence au inner class et non le java.lang.String standard. L’erreur ici provient du fait que Java considère « whizlab » comme un java.lang.String et ne sait pas quoi faire lors de l’affectation (=) considèrant que MyClass.String est incompatible à ce niveau. Non seulement cela l’incompatibilité se pose à chaque mention de String, y compris dans la signature de la méthode main ! Il fallait le savoir :) .

Pour terminer, voici ce qui aurait été nécessaire pour que le code compile correctement. Notez l’instanciation en chaîne qui est possible avec la dot notation.

class MyClass
{
    public static void main (java.lang.String[] args)
    {
        MyClass.String s = new MyClass().new String("whizlab");
        System.out.println(s);
    }
   
    public class String
    {
        private java.lang.String s;
       
        public String(java.lang.String s)
        {
            this.s = s;
            System.out.println("simulator");
        }
       
        public java.lang.String toString(){ // This is so output gives text value and not object hash
            return this.s;
        }
    }
}

- James Poulson.

Une réflexion au sujet de « Les inner class (question de certification OCJP) »

  1. Ping : Recap java, semaine 2, année 2013 | Blog de la rubrique java

Les commentaires sont fermés.