[静态内部类] 类声明中包含“static ”关键字的内部类。如以下示例代码:



public

  class  InnerClass 

java 静态内部类如何操作 java 内部类 静态内部类_外部类


{

    private static String nickName = "anan";

    private String name;

    private int age;

    

    public InnerClass(String name, int age)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.name = name;

        this.age = age;

    }

    

    public String getName()

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        return name;

    }

    public void setName(String name)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.name = name; 

    }

    

    public int getAge()

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        return age;

    }

    public void setAge(int age)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.age = age;

    }

    

    public static class Inner

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        private String heart = "zhaoli";

        public String getHeart()

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            return heart;

        }

        public void setHeart(String h)

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            this.heart = h;

        }

        

        public void print()

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            System.out.println(InnerClass.nickName);

            System.out.println(getHeart());

        }

    }

}


public  

class  InnerClassTest 

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

    public static void main(String[] args)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        InnerClass.Inner inner = new InnerClass.Inner();

        inner.print();

        inner.setHeart("simple-simply");

        inner.print();

    }

}

测试输出为:
anan
zhaoli
anan
simple-simply

这里说明public 修饰的静态内部类其实跟外部类的使用并没有太大区别,以“OuterClass.InnerClass”的方式来引用某个如此修饰的静态内部类。
<静态成员类特性>

  • 静态成员类可访问外部类的任一静态字段或静态方法
  • 像静态方法或静态字段一样,静态成员类有public/private/default权限修饰符

<静态成员类约束>

  • 静态成员类不能与外部类重名
  • 像外部类的静态方法一样,不能直接访问外部类的实例字段和实例方法
  • 静态成员类只能定义于外部类的顶层代码或外部类其它静态成员类的顶层代码中(嵌套定义);不能定义于外部类的某个函数中。

什么时候使用静态成员类
B为A的辅助类,且只为A所用时,可将B定义为A的静态成员类。例如JDK中的LinkedList类就有Entry静态成员类:


public   class

 LinkedList < E >   extends  AbstractSequentialList < E >  

   …;

    private  

static   class  Entry < E >  

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

    E element;

    Entry<E> next;

    Entry<E> previous;


    Entry(E element, Entry<E> next, Entry<E> previous) 

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.element = element;

        this.next = next;

        this.previous = previous;

    }

    }

    …;

}


  显然,Entry 用来表示LinkedList 中的一个结点,只被LinkedList

自身使用。


[非静态内部类] 一个静态成员类,若去掉“static ”关键字,就成为成员类:


public   class  InnerClass 


java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

    private static String nickName = "anan";

    private String name;

    private int age;

    

    public InnerClass(String name, int age)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.name = name;

        this.age = age;

    }

    

    public String getName()

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        return name;

    }

    public void setName(String name)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.name = name; 

    }

    

    public int getAge()

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        return age;

    }

    public void setAge(int age)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        this.age = age;

    }

    

    public class Inner

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        private String heart = "zhaoli";

        public String getHeart()

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            return heart;

        }

        public void setHeart(String h)

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            this.heart = h;

        }

        

        public void print()

        

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

            System.out.println(InnerClass.nickName);

            System.out.println(InnerClass.this.name);

            System.out.println(InnerClass.this.age);

            System.out.println(getHeart());

        }

    }

}


public   class  InnerClassTest 

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

    public static void main(String[] args)

    

java 静态内部类如何操作 java 内部类 静态内部类_外部类

{

        InnerClass outer = new InnerClass("simply-simple", 23);

        

        InnerClass.Inner inner = outer.new Inner();

        inner.print();

    }

} 测试输出为:

anan

simply-simple

23

zhaoli


类似于外部类的实例函数,成员类有public/private/default 权限修饰符

一个成员类实例必然所属一个外部类实例,成员类可访问外部类的任一个实例字段和实例函数。

一个成员类实例必然所属于其外部类的一个实例,那么如何在成员类内部获得其所属外部类实例呢?如示例代码所示,采用“OuterClass.this ”的形式。

指定内部类实例所属的外部类实例 内部类实例可在其外部类的实例方法中创建,此新创建内部类实例所属的外 部类实例自然就是创建它的外部类实例方法对应的外部类实例。

另外,如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部类实例,语法形式为:

OuterClass.InnerClass innerClass = outerClass.new InnerClass();


<成员类约束>

  • 成员类不能与外部类重名
  • 不能在成员类中定义static字段、方法和类(static final形式的常量定义除外)。因为一个成员类实例必然与一个外部类实例关联,这个static定义完全可以移到其外部类中去
  • 成员类不能是接口(interface)。因为成员类必须能被某个外部类实例实例化,而接口是不能实例化的。事实上,如示例代码所示,如果你以成员类的形式定义一个接口,该接口实际上是一个静态成员类,static关键字对inner interface是内含(implicit)的。

什么时候使用成员类

成员类的显著特性就是成员类能访问它的外部类实例的任意字段与方法。方便一个类对外提供一个公共接口的实现是成员类的典型应用。以JDK Collection类库为例,每种Collection类必须提供一个与其对应的Iterator实现以便客户端能以统一的方式遍历任一Collection实例。每种Collection类的Iterator实现就被定义为该Collection类的成员类。例如JDK中AbstractList类的代码片断:


public       abstract       class    AbstractList 
  < 
  E 
  > 
    
  extends 
   AbstractCollection 
  < 
  E 
  > 
    
  implements 
   List 
  < 
  E 
  > 
    
  
   {
    private class Itr implements Iterator<E> 
{
         ………;
    }

     public Iterator<E> iterator() 
{
        return new Itr();
     }
}



 因为定义在AbstractList 中的Itr 可访问AbstractList 中的任意字段和方法,所以很方便实现Iterator ,无需AbstractList 对外暴露更多的接口。

试想,如果没有成员类机制,只有在AbastractList源码之外定义一个实现Iterator的类Itr,该类有一个AbstractList实例成员list,为了Itr能获取list的内部信息以便实现遍历,AbstractList必然要向Itr开放额外的访问接口。