"private access" - Fehler mit Generika

Ich hatte ein problem konnte ich tatsächlich lösen mich, aber ich verstehe immer noch nicht, warum meine ursprüngliche code nicht funktioniert, oder wenn es eine elegantere Lösung als die, die ich gefunden. Ich präsentiere eine vereinfachte version meines Codes hier.

Betrachten Sie die folgende abstrakte Oberklasse X:

public abstract class X{

  private int i;

  public void m1(X x){
    x.i = 1; 
    m2(x);
  }

  public abstract void m2(X x);

}

Wenn m1 heißt, wir Bearbeiten ein privates Feld X der Instanz übergeben, und dann nennen wir m2 mit dieser Instanz.

Ich habe mehrere Unterklassen von X, Sie sind alle gleich in dem Sinne, dass Sie auch erklären, private Mitglieder, die Sie manipulieren. Um zu erreichen, dass Sie immer brauchen, um eine Besetzung zu Beginn von m2. Hier ist einer von Ihnen:

public class Y extends X{

  private int j;

  public void m2(X x){
     Y y = (Y) x;
     y.j = 0;
  }

}

Aber ich kann garantieren, dass jeder Aufruf von m1 in einer Instanz einer Unterklasse von X haben immer einen parameter des gleichen Typs, z.B. wenn ich eine Instanz von Y, die parameter der Methode m1 wird immer wieder eine Instanz von Y.

Wegen der Garantie, ich wollte die cast unnötig, durch die Einführung von Generika. Dies ist, wie ich möchte, dass meine Unterklassen Aussehen:

public class Y extends X<Y>{

  private int j;

  public void m2(Y y){
     y.j = 0;
  }

}

Wie funktioniert der Superklasse X muss schauen wie jetzt? Mein Erster Versuch war, dass:

public abstract class X<T extends X<T>>{

  private int i;

  public void m1(T x){
    x.i = 1; 
    m2(x);
  }

  public abstract void m2(T x);

}

Aber - das klappt nicht, wenn ich kompilieren, bekomme ich die folgende Fehlermeldung:

X.java:6: error: i has private access in X

Das ist in der Regel, was Sie bekommen, Sie versuchen, Zugriff auf die privaten member einer anderen Klasse. Offensichtlich Java nicht erkennen, dass T ist immer eine Instanz von X als gut, obwohl ich "T extends X" in der Erklärung.

Ich Feste X so:

public abstract class X<T extends X<T>>{

  private int i;

  public void m1(T x){
    X<?> y = x;
    y.i = 1; 
    m2(x);
  }

  public abstract void m2(T x);

}

Wenigstens bin ich nicht über CASTET - aber warum ist diese zusätzliche Zuweisung notwendig? Und warum nicht der original code funktioniert? Auch fand ich es seltsam, ich musste X<?> und konnten nicht X<T>.

InformationsquelleAutor Bernhard | 2013-12-19
Schreibe einen Kommentar