1、内部类(Inner Class),共分为4种:
1)静态内部类(static inner class):只能访问外部类的静态成员变量与静态方法,生成静态内部类对象的方法:外部类.静态内部类 变量名 = new 外部类.静态内部类();outerClass.InnerClass inner = new OuterClass.InnerClass();
class StaticInner { private static int a =4; public static class Inner { public void test() { System.out.println(a); } } } public class StaticInnerClass { public static void main(String[] args) { StaticInner.Inner inner = new StaticInner.Inner(); inner.test(); } }
这里Inner就是静态内部类,private static int a =4;这里的a变量必须是static的,如果去掉将出错,(静态的只能访问静态的),生成的class文件如下:StaticInner$Inner.class、StaticInner.class、StaticInnerClass.class,内部类的class名字为外部类名字+“$”+ 内部类定义的名字
2)成员内部类(member inner class):可以访问外部类的静态与非静态的方法与成员变量。生成成员内部类对象的方式为:
OuterClass.InnerClass inner = new OuterClass().new InnerClass();若想在成员内部类中访问外部类的成员变量,语法为: OuterClass.this.a;
class MemberInner { private int a = 4; public class Inner2 { private int a = 5; public void doSomething() { System.out.println(a);//当前对象的a,就是5 System.out.println(this.a);//当前对象的a,就是5 System.out.println(MemberInner.this.a);//外部类的变量a,是4 } } public void method() { Inner2 inner = this.new Inner2();// } } public class MemberInnerClassTest { public static void main(String[] args) { MemberInner.Inner2 inner = new MemberInner().new Inner2(); inner.doSomething(); } }
3)局部内部类(Local Inner Class):定义在方法当中,只能访问方法中声明的finally类型的变量。
class LocalInner { public void doSomething() { final int a = 4;//只有定义成final类型的变量,局部内部类才能访问 int b = 5; class Inner3 //局部内部类,只能访问final的局部变量 { public void test() { System.out.println("hello"); System.out.println(a); //System.out.println(b);这样写编译器报错 } } new Inner3().test(); } } public class LocalInnerClass { public static void main(String[] args) { LocalInner localInner = new LocalInner(); localInner.doSomething(); } }
4)匿名内部类(Anonymous Inner Class),是局部内部类的一种,没有类名字,没有关键字class、extends、implements,没有constructors,但是,
匿名内部类会隐式的继承一个父类或实现一个接口
import java.util.Date; public class AnonymousInnerClass { @SuppressWarnings("deprecation") public String get(Date date) { return date.toLocaleString(); } public static void main(String[] args) { AnonymousInnerClass test = new AnonymousInnerClass(); //String str = test.get(new Date()); //System.out.println(str); String str = test.get(new Date(){});//注意这里的get方法 //new Date(){}生成一个继承了Date的子类的一个对象。 //new Date(){},其一说明定义了一个匿名内部类;其二这个匿名内部类继承了Date类, // 其三,他没有重写Date类的任何方法 System.out.println(str); String str1 = test.get(new Date() { public String toLocaleString() //匿名内部类重写了Date类的toLocaleString方法 { return "hello"; } }); System.out.println(str1); } }
2、Swing使用匿名内部类的例子
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; public class SwingTest { public static void main(String[] args) { JFrame frame = new JFrame("frame"); JButton button = new JButton("click me"); //button.addActionListener(new MyListener());正常写法 button.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.out.println("hello"); } });//因为MyListener只有一个作用,所以可以使用匿名内部类,而取消MyListener //这时Swing大量使用的方式,也是匿名内部类的用处之一 frame.setSize(200, 200); frame.getContentPane().add(button); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } } /* class MyListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { System.out.println("hello"); } } */