Java內部類的訪問規則

BrightSea發表於2013-10-09

1.內部類可以直接訪問外部類中的成員,包括私有
      原因:因為在內部類中持有一個外部類的應用,格式:外部類.this

class Outer {
     private int x = 1;

     class Inner {
         int x = 2;
         public void seeOuter() {
              int x = 3;
              System.out.println(x);
              System.out.println(this.x);
              System.out.println(Outer.this.x);
        }
     }  
 }

 

2.外部類要訪問內部類,必須建立內部類物件

A.從外部類的非靜態方法中訪問內部類

class Outer {
  private int x = 1;

public void seeInner() {
   Inner in = new Inner();
   in.seeOuter();
  }

class Inner {
   public void seeOuter() {
    System.out.println(x);
   }
  }
 }

B、從外部類的靜態方法中訪問內部類

class Outer {
  private int x = 1;
  class Inner {
   public void seeOuter() {
   System.out.println(x);
   }
  }
  public static void seeInner(){
   Outer.Inner inner  = new Outer().new Inner(); //1
   //如果把1位置的訪問方式換成 new Inner().seeOuter() 必須保證Inner是靜態的
   inner.seeOuter();
  }
 }

C、在外部其它類中訪問內部類

class Outer {
  private int x = 1;
  class Inner {
   public void seeOuter() {
    ystem.out.println(x);
   }
  }
 }

public class Touter{
  public static void main(String[] args){
   Outer.Inner inner = new Outer().new Inner();
   inner.seeOuter();
  }
 
 }

對比:在外部類的非靜態方法中訪問內部類:Inner in = new Inner();
      在外部類的靜態方法中訪問內部類:Outer.Inner in = new Outer().new Inner();
      在外部其他類中訪問內部類:Outer.Inner in = new Outer().new Inner();

 

3.當內部類在成員位置上,就可以被成員修飾符修飾
3.1當內部類被static修飾後,就只能訪問外部類中的static成員,出現訪問侷限
  class Outer {
   private int x = 1;
   static class Inner {
    public void seeOuter() {
          System.out.println(x); //error
    }
   }
  } 

3.2在外部其他類中,如何訪問static內部類的非靜態成員呢?
  new Outer.Inner().seeOuter();
  理由:因為外部內一旦被載入,靜態內部類也被載入了,所以直接建立內部類物件呼叫方法即可

class Outer {
   private static int x = 1;
   static class Inner {
    public void seeOuter() {
    System.out.println(x);
    }
   }
  }
  public class Test{
   public static void main(String[] args){
    new Outer.Inner().seeOuter();
   } 
  }

3.3在外部其他類中,如何訪問static內部類的靜態成員呢?
    Outer.Inner.seeOuter();

class Outer {
   private static int x = 1;
   static class Inner {
    public static void seeOuter() {
    System.out.println(x);
    }
   }
  }
  public class Test{
   public static void main(String[] args){
    new Outer.Inner().seeOuter();
   } 
  }

3.4.當內部類中定義了靜態成員,該內部類必須是靜態的
  class Outer {
   private static int x = 1;
   class Inner {
    static int y = 2; //error
    public static void seeOuter() { //error
     System.out.println(x);
    }
   }
  }  

3.5.當內部類中的靜態方法訪問內部類時,內部類也必須是靜態的(參考上面2中B位置1處)

 

4.方法內部類(區域性內部類)
  把類放在方法內

  class Outer {
         public void doSomething(){
             class Inner{
                  public void seeOuter(){  
                  }
              }   
         }
  }

4.1、方法內部類只能在定義該內部類的方法內例項化,不可以在此方法外對其例項化

4.2、方法內部類物件不能訪問該內部類所在方法的非final區域性變數  
     class Outer {
     int b = 1;
         public void doSomething(){
              final int a =10;
              class Inner{
                   public void seeOuter(){
                       System.out.println(a);// a 必須是final型別
     System.out.println(b);// b 可以不是final型別的
                  }
              }  
              Inner in = new Inner();
              in.seeOuter();   //只能在方法內部訪問內部類
         }
         public static void main(String[] args) {
              Outer out = new Outer();
              out.doSomething();
         }
     }

4.3、方法內部類的修飾符
     與成員內部類不同,方法內部類更像一個區域性變數
     可以用於修飾方法內部類的只有final和abstract

4.4、靜態方法內的方法內部類

     靜態方法是沒有this引用的,因此在靜態方法內的內部類遭受同樣的待遇,即:只能訪問外部類的靜態成員

5.匿名內部類
    匿名內部類就是內部類的簡寫格式
    定義匿名內部類的前提:內部類必須繼承一個類或實現介面
    匿名內部類就是一個匿名子類物件
  格式:new 父類或者介面(){定義子類的內容}

相關文章