首页 > 代码库 > Java内部类

Java内部类

Java内部类,我们不常用,今天有看了下,就做个笔记标记下。

内部类是指在一个类的内部或类的成员方法中再定义一个类。内部类名没有和文件同名的限制,只要符合类名称规范就行。内部类可以是静态static的,也可用public,default,protected和private修饰。而外部类只能使用public和default,对于外部顶级类还要加类名必须和文件名相同。内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两个类。对于一个名为Outer的外部类和其内部定义的名为Inner的内部类。编译完成后出现Outer.class和Outer$Inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

内部类分为:1.成员内部类;2.局部内部类;3.静态内部类(嵌套内部类);4.匿名内部类

1.成员内部类

成员内部类,是指将内部类可以看作外部类的一个成员,内部类可以直接使用外部类的所有成员和方法,即使是private描述的。但外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来访问。由于成员内部类需要先创建了外部类,才能创建它自己的,因此成员内部类不能有static属性/方法,也不能包含静态内部类。

在成员内部类要引用外部类对象时,使用外部类.this来表示外部类对象,如:Outer.this。

 1 public class Outer {
 2 
 3     private String type;
 4 
 5     public static void main(String[] args) {
 6         Outer outer = new Outer();
 7         Outer.Inner inner = outer.new Inner();
 8         //Outer.Inner inner = new Outer().new Inner();
 9         inner.print("Hello World!");
10     }
11 
12     public class Inner {
13         private String type;
14 
15         public void print(String str) {
16             System.out.println(Outer.this.type);
17             System.out.println(str);
18         }
19     }
20 }

成员内部类创建 Outer.Inner inner = new Outer().new Inner(); 。成员内部类的对象属于外部类对象,因此要创建内部类,必须创建外部类对象。

2.局部内部类

局部内部类,是指内部类定义在方法和作用域内。局部内部类也像别的类一样进行编译,但只是作用域不同而已,只在该方法或作用域内才能使用,退出这些作用域后无法引用的。

3.静态内部类(嵌套内部类)

静态内部类,就是修饰为static的内部类。声明为static的内部类,可以看作内部类是外部类类的静态成员,就是说我们可以直接引用Outer.Inner。静态内部类不能声明为private,一般声明为public。静态内部类可以包含内部类。

 1 public class Outer {
 2 
 3     static String type;
 4 
 5     public static void main(String[] args) {
 6         Outer.Inner inner = new Outer.new Inner();
 7         inner.print("Hello World!");
 8     }
 9 
10     static public class Inner {
11         private String type;
12 
13         public void print(String str) {
14             System.out.println(Outer.type);
15             System.out.println(str);
16         }
17     }
18 }

静态内部类创建 Outer.Inner inner = new Outer.new Inner(); 。静态内部类属于外部类,通过类名调用创建。

4.匿名内部类

匿名内部类隐式地继承了一个父类或者实现了一个接口。有时候某个内部类只创建一个对象,我为了不对这个内部类命名,便倾向于使用匿名内部类。由于构造器的名字必须和类名相同,而匿名内部类没有类名,所以匿名类不能有自己的构造器。

对于匿名内部类,我们使用的还是挺多的,像模版方法中的回调函数或叫钩子函数;还有像Andorid的组件的监听器的注册等等,为了方便,一般会采用匿名内部类。

下面看一个Android中的按钮点击事件的注册的例子

 1 ((Button) findViewById(R.id.loginButton)).setOnClickListener(new Button.OnClickListener() { 
 2     @Override
 3     public void onClick(View v) {
 4         new Thread() {
 5             @Override 
 6             public void run() {
 7                 // TODO Auto-generated method stub 
 8             } 
 9         }.start(); 
10     }
11 }); 

对于这段代码实际上创建了两个匿名内部类:1.Button.OnClickListener;2.Thread。

对于匿名内部类的使用,有一下方面需要注意:

1. 当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。如果有需要,也可以重写父类中的普通方法。
2. 如果匿名内部类需要访问外部类的局部变量,则外部类的局部变量必须使用final修饰符来修饰。(在JDK8中,我们不用写final修饰符也不会报错,但对于JVM实际依旧是按照final常量来处理)