2016-01-18 3 views
-1

J'ai quelques classes imbriquées l'une dans un autreAucune instance englobante est portée avec initializers double accolade

public abstract class I 
{ 
    public abstract int f(); 
} 

public class J 
{ 
    private List<I> li; 
    public J(List<I> l) 
    { 
     li = l; 
    } 
} 

public class A // first class 
{ 
    private int x; // field of A 
    public class B extends J // second class 
    { 
     public B() 
     { 
      super(new ArrayList<I>() // super call 
      {{ // array initializer 
       add(new I() // third class 
       { 
        @Override 
        public int f() 
        { 
         return x; // <- here!!! 
        } 
       }); 
      }}); 
     } 
    } 
} 

Dans ces conditions, je reçois l'erreur: « erreur: aucune instance englobante de type A est portée » . Suppression d'un élément de cette installation corrige cette erreur. En outre, prendre x et l'enregistrer dans une autre variable, puis utiliser cette variable fonctionne également.

Que se passe-t-il ici? Cela ressemble à un bug dans un compilateur pour moi.

+1

Vous pouvez déclarer 'x' comme' static' ou 'final' afin de corriger la portée. – LordAnomander

+0

Le hack double-brace est un anti-modèle, et vous feriez mieux de ne pas l'utiliser. – chrylis

+0

Il serait préférable d'utiliser Arrays.asList que le hack double-accolade. Mais ce n'est pas le problème ici. Le champ x doit être déclaré 1/comme final, statique ou non, et avec un initialiseur car il ne peut pas être initialisé dans le ctor de B avant d'appeler super (...) 2/ou comme – atao

Répondre

0

Il est interdit d'avoir 2 classes publiques dans un fichier Java et le nom de fichier doit être identique au nom de classe publique.

+0

statique je sais et cela est complètement hors sujet. – haael

0

Pour expérimenter avec votre code j'ai fait une nouvelle classe Test comme ceci. Je ne vois aucune erreur signalée (en utilisant Java 8). C'est peut-être un problème de construction.

public class Test { 

    public abstract class I { 

     public abstract int f(); 
    } 

    public class J { 

     private List<I> li; 

     public J(List<I> l) { 
      li = l; 
     } 
    } 

    public class A // first class 
    { 

     private int x; // field of A 

     public class B extends J // second class 
     { 

      public B() { 
       super(new ArrayList<I>() // super call 
       { 
        { // array initializer 
         add(new I() // third class 
         { 
          @Override 
          public int f() { 
           return x; // <- here!!! 
          } 
         }); 
        } 
       }); 
      } 
     } 
    } 

    public void test() { 
     System.out.println("Hello"); 
    } 

    public static void main(String args[]) { 
     //<editor-fold defaultstate="collapsed" desc="test"> 
     try { 
      new Test().test(); 
     } catch (Throwable t) { 
      t.printStackTrace(System.err); 
     } 
     //</editor-fold> 
    } 
} 

Java 7 semble également accepter ce code.