天天看点

Java内部类学习总结

    Java内部类的意思就是定义在类中的类。一般来说可以分为四种:静态内部类、成员内部类、局部内部类以及匿名内部类。

    简单描述一下几种内部类的定义方式,以及访问方式吧,实际开发中自己目前应用到内部类的情况还不多,只在一个tasksend工具类的编写中用过匿名内部类的方式,对于使用的新的慢慢总结吧。

一、静态内部类(Static Inner Class)

用static关键字修饰的内部类为静态内部类.

定义静态内部类:

package com.hdjava.innerclass;

public class StaticInnerClass {

    private static int a = 1;

    public static void output(){

       System.out.println("这是外部类的静态方法");

    }

    @SuppressWarnings("unused")

    public static class StaticInner{

       public void method(){

           System.out.println("访问外部类的静态变量 a:"+ a);

           output();

       }

    }

}

测试类:

package com.hdjava.innerclass;

public class StaticInnerClassTest {

    public static void main(String[] args) {

       StaticInnerClass.StaticInner innerClass = new StaticInnerClass.StaticInner();

       innerClass.method();

    }

}

运行结果:

访问外部类的静态变量 a:1

这是外部类的静态方法

分析:

静态内部类只能访问外部类的静态成员变量与静态方法,生成静态内部类对象的方式为:

outerClass.InnerClass inner = new OuterClass.InnerClass()

二、成员内部类

成员内部类(Member Inner Class): 可以访问外部类的静态与非静态的方法与成员变量。

定义成员内部类:

package com.hdjava.innerclass;

public class MemberInnerClass {

    private int a = 1;

    public  void output(){

       System.out.println("这是外部类的方法");

    }

    @SuppressWarnings("unused")

    public  class MemberInner{

       private int a = 2;

       public void method(){

System.out.println("访问外部类的变量 a:"+ (MemberInnerClass.this).a);

           System.out.println("访问内部类的变量 a:"+ a);

           output();

       }

    }

}

测试类:

package com.hdjava.innerclass;

public class MemberInnerClassTest {

    public static void main(String[] args) {

       MemberInnerClass.MemberInner  memberInner = (new MemberInnerClass()).new MemberInner();

       memberInner.method();

    }

}

运行结果:

访问外部类的变量 a:1

访问内部类的变量 a:2

这是外部类的方法

分析:

1、生成成员内部类对象的方式为:

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

若想在局部内部类中访问外部类的与你内部类中成员变量重名成员变量,语法为:

OuterClass.this.a

三、局部内部类

局部内部类(Local Inner Class):定义在方法当中的内部类,声明周期随方法而定

定义局部内部类:

package com.hdjava.innerclass;

public class LocalInnerClass {

    public void output(){

       final int var = 1;

       System.out.println("this is outClass's method output");

        class InnerClass{

           public void output(){

              System.out.println("this is innerClass's method output");

              System.out.println("outClass'field var="+var);

           }

       }

       InnerClass in = new InnerClass();

       in.output();

    }

}

测试类:

package com.hdjava.innerclass;

public class LocalInnerClassTest {

    public static void main(String[] args) {

       LocalInnerClass test = new LocalInnerClass();

       test.output();

    }

}

运行结果:

this is outClass's method output

this is innerClass's method output

outClass'field var=1

分析:只能访问方法中声明的final类型的变量

四、匿名内部类

匿名内部类(Anonymous Inner Class):匿名内部类会隐式地继承一个父类或实现一个接口。

定义任意一个类,供匿名内部类继承用:

package com.hdjava.innerclass;

public class AnonymoursClass {

    public void output(){

       System.out.println("this is method output ");

    }

}

测试类:

package com.hdjava.innerclass;

public class AnonymoursClassTest {

    public static void main(String[] args) {

       AnonymoursClass test1 = new AnonymoursClass();

       test1.output();

       AnonymoursClass test2 =  new AnonymoursClass (){

           public void output(){

              System.out.println("this is Anonymours class'method output");

           }

       };

              test2.output();

    }

}

运行结果:

this is method output

this is Anonymours class'method output

下面摘录一些在其他文章中看到的关于内部类的观点:

A、内部类仍然是一个独立的类,在编译之后会内部类会被编译成独立的.class文件,但是前面冠以外部类的类命和$符号。

B、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的。

C、普通的类可以用this引用当前的对象,内部类也是如此。但是假若内部类想引用外部类当前的对象呢?用“外部类名”.this

D、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。

以上A-D摘自: http://www.blogjava.net/raylong1982/archive/2007/10/24/155439.html

E、在成员内部类中,可以使用外围类的字段成员变量。那么,它是如何实现的呢? 是这样的,用外围类创建内部类对象时,此内部类对象会秘密的捕获一个指向外围类的引用,于是,可以通过这个引用来访问外围类的成员。通常,这些都是编译器来处理,我们看不到,也不用关心这个。 正是因为如此,我们创建内部类对象时,必须与外围类对象相关联。

F、 内部类最大好处就是保持跟外部类的生命周期一致,可以通过管理一个类的生命周期来维护俩个类的生命周期在线成池,连接池,通信套接字是必然用到的这些要求内存管理很高的时候,对类的生命是必须负责的,但过多的类不好维护,通常为便于方便维护,就将归纳并放在一起。

以上E-F摘自http://www.iteye.com/topic/939534?page=3

G、如果你声明的成员类不要求访问外围实例,那么请记住把 static 修饰符放到成员类的声明中,使它成为一个静态成员类,而不是一个非静态成员类 。如果你省略了 static 修饰符,则每个实例都将包含一个额外的指向外围对象的引用 。维护这份引用要消耗时间和空间,但又没有相应的好处 。如果在没有外围实例的情况下,你也要分配实例的话,则不能使用非静态成员类,因为非静态成员类的实例必须要有一个外围实例。

以上G摘自http://xutao5641745.iteye.com/blog/939912