Oggetto della classe interna

Sep 19 2020

Non sono riuscito a capire il comportamento del codice seguente.

La mia aspettativa era che dovesse stampare 100 in entrambi i println()metodi. Perché il risultato è diverso?

Se rimuovo il commento getX()nella classe interna, l'output di println() metodi è lo stesso che è 100.

Non riuscivo a capire il ragionamento di un comportamento diverso. Per favore aiutami a capire.

public class Foo {

    public static void main(String[] args) {
        MyOuter outerObj = new MyOuter();
        MyOuter.MyInner innerObj = outerObj.new MyInner();

        innerObj.setX();

        System.out.println("x: " + innerObj.getX()); //x: 3
        System.out.println("x: " + outerObj.getX()); //x: 100
    }
}
class MyOuter {
    private int x = 3;

    public int getX() { return x; }

    class MyInner extends MyOuter {
        public void setX(){ x = 100; }
//      public int getX() { return x; }
    }
}

Risposte

4 Turing85 Sep 19 2020 at 05:26

Dal MyInnerpunto di vista di, ci sono due private int xcampi in gioco qui:

  • Un campo super.xereditato da MyOuter, ma inaccessibile perché dichiarato come privatee MyInnercome oggetto che eredita non può accedere a questo campo.
  • Un campo MyOuter.this.xdal circostante MyOuter -instance (poiché MyInnerè un non-statico) classe interna (, è sempre limitata al caso del circostante MyOuter), che è accessibile.

Il metodo setX()in MyInnernon può accedere al campo ereditato super.x, quindi accede al campo MyOuter.this.xe imposta i suoi valori su 100. Una chiamata consecutiva sulle circostanti MyOuters' getX()tornerà 100.

La chiamata innerObj.getX()(che è ereditata da MyOutere può accedere super.x) restituisce il valore del campo ereditato super.x(che ha ancora il suo valore iniziale di 3).

Se rimuoviamo extends MyOuterda e includiamo il getX()-metodo in MyInner, il codice si comporta come previsto.


Il fatto che MyInnernon possa accedere al campo ereditato private xè inizialmente protectedfonte di confusione, ma il comportamento è in realtà in linea con il comportamento della parola chiave nel contesto dei metodi statici nelle classi ereditate come discusso in questo post di Hariharan