一、JAVA中内部类与匿名内部类的区别
内部类:内部类可以是静态类或非静态类。 静态内部类只包含静态方法和静态类变量,只能访问外部类的静态元素。 内部类可以实例化并多次使用。
匿名内部类:不区分静态和非静态,只能使用一次。 如果使用外部类的变量,则必须是类变量或实例变量。 也就是说,它必须是类定义的变量或final的局部变量。 匿名内部类继承某个类就可以重写该类的方法,这与普通内部类相同。
总结:所有可以使用匿名内部类的地方都可以用内部类替换,但是用匿名内部类编码非常简洁、易于阅读。 除非需要多次使用该内部类,否则建议使用匿名内部类。
二、内部班级使用时机
1、实现事件侦听器时(例如,动作监听器。 采用内部类很容易实现)
2、创建事件驱动(注意内部类的对象包括私有成员,可以访问外部类的成员方法和变量);
3、功能实现后,为了节约编译后生成的字节码(内部类可以减少字节码文件,即java文件编译后的. class文件)。
三.匿名内部类使用时机
匿名内部类是内部类的特殊情况。 只有一个实例,没有引用。 因此,通常可以在内部类中实现,但在只有一个实例的情况下使用它(可以减少资源开销);
=====================================
匿名内部类,即未命名的内部类
因为没有名称,所以匿名内部类只能使用一次。 通常用于简化代码的编写
但是,要使用匿名内部类,还必须继承父类或实现接口,这也是前提条件
1 .匿名内部类的基本实现
abstract class person { publicabstractvoideat (;
公共类演示{公共staticvoidmain (字符串[ ] args ) }
人员=新人员({ public void eat } )
system.out.println (eat something );
}
(;
p.eat (;
}
}
执行结果: eat something
可以看到用大括号直接实现了抽象类Person的方法
这样可以省略类的表示
另外,匿名内部类也可以用于接口
2 .在接口中使用匿名内部类
接口人员{公共语音(;
公共类演示{公共staticvoidmain (字符串[ ] args ) }
人员=新人员({ public void eat } )
system.out.println (eat something );
}
(;
p.eat (;
}
}
执行结果: eat something
从上面的示例可以看到,只要一个类是抽象或接口,该子类中的方法就可以使用匿名内部类实现
多线程在多线程实现中最常用,因为它必须继承Thread类或Runnable接口
3.Thread类的匿名内部类实现
公共类demo { publicstaticvoidmain (字符串[ ] args ) }
Thread t=newThread () {public voidrun ) for ) intI=1; i=5; I ) {
system.out.print(I ' );
}
}
(;
t.start (;
}
}
执行结果:1 2 3 4 5
4.Runnable接口的匿名内部类实现
公共类demo { publicstaticvoidmain (字符串[ ] args ) }
Runnable r=newRunnable () {public voidrun ) ) for ) intI=1; i=5; I ) {
system.out.print(I ' );
}
}
(;
threadt=newthread(r;
t.start (;
}
}
执行结果:1 2 3 4 5
以下是内部类
示例1 :内部类的基本结构
//外部类
类out { pri
vate int age = 12;//内部类classIn {public voidprint() {
System.out.println(age);
}
}
}public classDemo {public static voidmain(String[] args) {
Out.In in= new Out().newIn();
in.print();//或者采用下种方式访问
/*Out out = new Out();
Out.In in = out.new In();
in.print();*/}
}
运行结果:12
从上面的例子不难看出,内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢?
因为内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象,这也是内部类的唯一优点
如同心脏可以直接访问身体的血液,而不是通过医生来抽血
实例2:静态内部类
classOut {private static int age = 12;static classIn {public voidprint() {
System.out.println(age);
}
}
}public classDemo {public static voidmain(String[] args) {
Out.In in= newOut.In();
in.print();
}
}
运行结果:12
可以看到,如果用static 将内部内静态化,那么内部类就只能访问外部类的静态成员变量,具有局限性
其次,因为内部类被静态化,因此Out.In可以当做一个整体看,可以直接new 出内部类的对象(通过类名访问static,生不生成外部类对象都没关系)
实例3:方法内部类
classOut {private int age = 12;public void Print(final intx) {classIn {public voidinPrint() {
System.out.println(x);
System.out.println(age);
}
}newIn().inPrint();
}
}public classDemo {public static voidmain(String[] args) {
Out out= newOut();
out.Print(3);
}
}
运行结果:
3
12
在上面的代码中,我们将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方法
如果此时我们需要往外部类的方法中传入参数,那么外部类的方法形参必须使用final定义
至于final在这里并没有特殊含义,只是一种表示形式而已