静态内部类详解

什么是静态内部类?

有static关键字修饰的内部类。

比如:Pattern类中的Node类。


注意:

静态内部类访问外部类的静态成员变量或方法必须是静态的。


代码:

public class Outer {
    private static String s1 = "this is s1 in Outer";
    private static String s2 = "this is s2 in Outer";

    public void method1() {
        // 外部类可通过内部类的对象调用内部类的私有成员变量或方法
        System.out.println(new Inner().s1);
        System.out.println(new Inner().method2());
    }

    private static String method2() {
        return "this is method2 in Outer";
    }

    // 内部静态类
    public static class Inner {
        private String s1 = "this is s1 in Inner";
        private static String s3 = "this is s3 in Inner";

        public void method1() {
            // 内部类可直接访问外部类的私有静态成员变量或方法
            System.out.println(s2);
            // 内部类和外部类有同名变量和方法时
            System.out.println(s1);
            System.out.println(Outer.s1);
            System.out.println(method2());
            System.out.println(Outer.method2());
        }

        private String method2() {
            return "this is method2 in Inner";
        }
    }
}

调用:

public class MainClass {
    public static void main(String[] args) {
        Outer outer = new Outer();
        System.out.println("------外部类测试--------");
        outer.method1();
        System.out.println("------内部类测试--------");
        Outer.Inner inner = new Outer.Inner();
        inner.method1();
    }
}

打印:

------外部类测试--------
this is s1 in Inner
this is method2 in Inner
------内部类测试--------
this is s2 in Outer
this is s1 in Inner
this is s1 in Outer
this is method2 in Inner
this is method2 in Outer

分析:

反编译后自动生成文件:Outer$Inner.class

Outer 反编译代码1:

public class jichu.Outer {
  private static java.lang.String s1;
  private static java.lang.String s2;
  static {};
  public jichu.Outer();
  public void method1();
  private static java.lang.String method2();
  static java.lang.String access$0();
  static java.lang.String access$1();
  static java.lang.String access$2();
}

Outer 反编译代码2:

public class Outer
{
  private static String s1 = "this is s1 in Outer";
  private static String s2 = "this is s2 in Outer";
  
  public void method1()
  {
    System.out.println(new Inner().s1);
    System.out.println(new Inner().method2());
  }
  
  private static String method2()
  {
    return "this is method2 in Outer";
  }
  
  public static class Inner
  {
    private String s1 = "this is s1 in Inner";
    private static String s3 = "this is s3 in Inner";
    
    public void method1()
    {
      System.out.println(Outer.s2);
      
      System.out.println(this.s1);
      System.out.println(Outer.s1);
      System.out.println(method2());
      System.out.println(Outer.access$2());
    }
    
    private String method2()
    {
      return "this is method2 in Inner";
    }
  }
}

Outer$Inner 反编译代码1:

public class jichu.Outer$Inner {
  private java.lang.String s1;
  private static java.lang.String s3;
  static {};
  public jichu.Outer$Inner();
  public void method1();
  private java.lang.String method2();
  static java.lang.String access$0(jichu.Outer$Inner);
  static java.lang.String access$1(jichu.Outer$Inner);
}

Outer$Inner 反编译代码2:

public class Outer$Inner
{
  private String s1 = "this is s1 in Inner";
  private static String s3 = "this is s3 in Inner";
  
  public void method1()
  {
    System.out.println(Outer.access$0());
    
    System.out.println(this.s1);
    System.out.println(Outer.access$1());
    System.out.println(method2());
    System.out.println(Outer.access$2());
  }
  
  private String method2()
  {
    return "this is method2 in Inner";
  }
}

MainClass反编译代码:

public class MainClass
{
  public static void main(String[] args)
  {
    Outer outer = new Outer();
    System.out.println("------外部类测试--------");
    outer.method1();
    System.out.println("------内部类测试--------");
    Outer.Inner inner = new Outer.Inner();
    inner.method1();
  }
}

1、创建静态内部类方式:Outer.Inner inner = new Outer.Inner()静态内部类不依赖于外部类

2、外部类可通过内部类的对象调用内部类的私有成员变量或方法。

3、静态内部类访问的外部类成员变量或方法为什么不能是非静态的,而成员内部类可以?

成员内部类中Outer$Inner反编译代码1中有:

  final jichu.Outer this$0;
  public jichu.Outer$Inner(jichu.Outer);

可以看出成员内部类中有外部类的引用,所以成员内部类对外部类的私有非静态变量和方法可以随意访问。

从静态内部类Outer$Inner反编译代码1中可以看出它不存在对外部类的引用,所以仅能访问外部类的静态成员变量或方法

4、静态内部类中可定义静态的成员变量和方法。


总结

1、创建静态内部类方式:Outer.Inner inner = new Outer.Inner();静态内部类不依赖于外部类。

2、外部类可通过内部类的对象调用内部类的私有成员变量或方法。

3、静态内部类访问外部类的静态成员变量或方法必须是静态的。

4、静态内部类中可定义静态的成员变量和方法。

5、外部类可以创建静态内部类的实例,即使是私有的;并可通过内部类的实例访问内部类的成员变量和方法,即使是私有的。

 

posted @ 2016-11-28 18:10  SQP51312  阅读(2494)  评论(0编辑  收藏  举报