原文:http://www.javaworld.com/article/2077372/learn-java/static-class-declarations.html
为了理解static关键字在类声明中的使用,首先我们需要了解类声明。有两种类,一种是top-level class;一种是inner class。
Top-level classes
top-level class可以被声明为包成员,每一个top-level类对应于一个文件名与类名相同的java文件。
因为top-level class已经是top-level,所以没必要声明为static。如果把top-level class声明为static,编译器会报错。
Inner classes
在top-level class中可以定义inner class,根据inner class定义方式的不同,inner class可以有如下四种形式:
1. Anonymous:匿名类的声明和初始化在同一条语句中。匿名类没有类名,并且只能被实例化一次。例子如下:
okButton.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e){ dispose(); } });
因为匿名类没有标准的类声明,所以不可以声明为static。
2. Local.
局部类就像局部变量一样,它的创建和使用都在一个代码块中。一旦你在代码块中声明类,那么在这个代码块中你就可以多次实例化该类。就像局部变量一样,局部类不能声明为public,private,protected或static。
例子如下:
//some code block .......{ class ListListener implements ItemListener { List list; public ListListener(List l) { list = l; } public void itemStateChanged(ItemEvent e) { String s = l.getItemSelected(); doSomething(s); } } List list1 = new List(); list list2 = new List(); list1.addItemListener(new ListListener(list1)); list2.addItemListener(new ListListener(list2)); }
3. Member.
成员类是定义在另一类中的。在包含该成员类的类中,成员类可以在任意一处位置使用。
成员内部类是唯一可以声明为static类,当把成员类声明为static的时候,它就变成top-level class。
例子如下:
//外部类 class Out { private int age = 12; //内部类 class In { public void print() { System.out.println(age); } } } public class Demo { public static void main(String[] args) { Out.In in = new Out().new In(); in.print(); //或者采用下种方式访问 /* Out out = new Out(); Out.In in = out.new In(); in.print(); */ } }
class Out { private int age = 12; class In { private int age = 13; public void print() { int age = 14; System.out.println("局部变量:" + age); System.out.println("内部类变量:" + this.age); System.out.println("外部类变量:" + Out.this.age); } } } public class Demo { public static void main(String[] args) { Out.In in = new Out().new In(); in.print(); } }
内部类在没有同名成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量,而无需指定Out.this.属性名
否则,内部类中的局部变量会覆盖外部类的成员变量。
4. Nested top-level.
nested top-level class是带static修饰符的成员类。netsted top-level class可以非常方便的把相关类组织到一起,而不需要创建新包。
例子如下:
public class Filter { Vector criteria = new Vector(); public addCriterion(Criterion c) { criteria.addElement(c); } public boolean isTrue(Record rec) { for(Enumeration e=criteria.elements(); e.hasMoreElements();) { if(! ((Criterion)e.nextElement()).isTrue(rec)) return false; } return true; } public static class Criterion { String colName, colValue; public Criterion(Stirng name, String val) { colName = name; colValue = val; } public boolean isTrue(Record rec) { String data = rec.getData(colName); if(data.equals(colValue)) return true; return false; } } } Filter f = new Filter(); f.addCriterion(new Filter.Criterion("SYMBOL", "SUNW")); f.addCriterion(new Filter.Criterion("SIDE", "BUY")); ..... if(f.isTrue(someRec)) //do some thing .....
可以看到,如果用static 将内部内静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性
其次,因为内部类被静态化,因此Out.In可以当做一个整体看,可以直接new 出内部类的对象(通过类名访问static,生不生成外部类对象都没关系)