2009-02-11 6 views
5

Um auf das Feld x einer äußeren Klasse A von einer inneren Klasse B zuzugreifen, stelle ich fest, dass Sie "A.this.x" verwenden können. Aber was, wenn die äußere Klasse auch anonym ist? Zum BeispielZugriff auf ein Feld einer äußeren anonymen Klasse aus einer inneren anonymen Klasse

public class Main1 { 
    public static void main(String[] args) { 
     Comparable c1 = new Comparable(){ 
      int x = 3; 
      public int compareTo(Object o) { 
       Comparable c2 = new Comparable(){ 
        int x = 4; 
        public int compareTo(Object o) { 
         return x; // <-- THIS LINE 
        } 
       }; 
       return c2.compareTo(o); 
      } 
     }; 
     System.out.println(c1.compareTo(null)); 
    } 
} 

Wenn dieser Code ausgeführt wird, wird der Wert von 4 gedruckt, da der Wert von c2 Feld x ist. Ich möchte jedoch die Zeile "THIS LINE" so ändern, dass sie das x der äußeren Klasse zurückgibt (also das Feld x von c1 mit dem Wert 3). Wenn die äußeren Klasse (das heißt, c1 Klasse) eine benannte Klasse A war, dann konnte ich

return x; 

mit

return A.this.x; 

ersetzen Aber da die äußeren Klasse auch anonym ist, habe mich nicht ein Name zu verwenden.

Frage: Gibt es eine Möglichkeit, die Zeile "THIS LINE" so zu ändern, dass sie sich auf c1s Feld x und nicht auf c2 bezieht, ohne die anonymen Klassen in benannte Klassen zu ändern?

Ich realisiere, dass dieser Code ist wirklich hässlich und es ist nicht gut Programmierstil auf diese Weise anonyme Klassen zu verwenden, aber der Code wird von einem anderen Programm generiert, und dies ist der einfachste Weg, den Generator zu implementieren.

Antwort

4

Ich würde vermeiden, die andere Variable zu verbergen, indem Sie einen anderen Namen als x wählen.

0

Ich glaube, dass Sie die Felder endgültig erklären müssen - der Code, den Sie dort haben, kompiliert nur wegen der Beschattung, über die Sie sich beschweren . Nicht wahr.

Das sieht wie ein klassischer Fall aus, wo etwas wie Lisps gensym die Dinge einfacher machen wird. Mit anderen Worten, der Codegenerator verwendet unterschiedliche Identifikatoren für diese Variablen - z. x1 und x2.

+0

Die Felder müssen nicht endgültig sein; das ist nur für Parameter/lokale Variablen. Wenn er das äußere Feld 'y' nannte, konnte er von der innersten Klasse darauf zugreifen. –

2

Die einfache Antwort ist nicht die Variablen Schatten:

public static void main(String[] args) { 
    Comparable c1 = new Comparable() { 
     int x = 3; 
     public int compareTo(Object o) { 
      Comparable c2 = new Comparable() { 
       //changed this name 
       int y = 4; 
       public int compareTo(Object o) { 
        return x; 
       } 
      }; 
      return c2.compareTo(o); 
     } 
    }; 
    System.out.println(c1.compareTo(null)); 
} 

Ausgang:

Vorausgesetzt, dass Sie mit generierten Code arbeiten, ist dies eine Option für Du?

1

AFAIK gibt es keine Möglichkeit zu erreichen, was Sie wollen. Wenn Sie den Code ändern können (wie es Ihnen möglich erscheint), aber nicht in benannte Klassen ändern möchten, können Sie einfach den Namen der Variablen ändern, so dass Sie keine Probleme mit dem Gültigkeitsbereich haben? Sie sollten sie für Klarheit sowieso umbenennen

1

Klassen sind anonym - namenlos. Keine Möglichkeit, über Namensreferenz auf ihre Felder zuzugreifen. Es gibt keinen Namen.