匿名内部类精讲
Java中内部类详解—匿名内部类

Java中内部类详解 —匿名内部类
什么是内部类?
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。
成员内部类
定义在类中方法外的类。
定义格式:
class 外部类 { class 内部类{ }
}
在描述事物时,若一个事物内部还包含其他事物,就可以使用内部类这种结构。比如,汽车类Car 中包含发动机类Engine ,这时,Engine就可 以使用内部类来描述,定义在成员位置。
}
创建匿名内部类,并调用:
public class InnerDemo { public static void main(String[] args) { /* 1.等号右边:是匿名内部类,定义并创建该接口的子类对象 2.等号左边:是多态赋值,接口类型引用指向子类对象 */ FlyAble f = new FlyAble(){ public void fly() { System.out.println("我飞了~~~"); } };
}
以上两步,也可以简化为一步,代码如下:
public class InnerDemo3 { public static void main(String[] args) { /* 创建匿名内部类,直接传递给showFly(FlyAble f) */ showFly( new FlyAble(){ public void fly() { System.out.println("我飞了~~~"); } }); }
}
定义测试类:
public class InnerDemo { public static void main(String[] args) { // 创建外部类对象 Person p = new Person(); // 创建内部类对象 Heart heart = p.new Heart();
java中的匿名内部类总结

java中的匿名内部类总结java中的匿名内部类总结匿名内部类也就是没有名字的内部类正因为没有名字,所以匿名内部类只能使⽤⼀次,它通常⽤来简化代码编写但使⽤匿名内部类还有个前提条件:必须继承⼀个⽗类或实现⼀个接⼝实例1:不使⽤匿名内部类来实现抽象⽅法abstract class Person {public abstract void eat();}class Child extends Person {public void eat() {System.out.println("eat something");}}public class Demo {public static void main(String[] args) {Person p = new Child();p.eat();}}运⾏结果:eat something可以看到,我们⽤Child继承了Person类,然后实现了Child的⼀个实例,将其向上转型为Person类的引⽤但是,如果此处的Child类只使⽤⼀次,那么将其编写为独⽴的⼀个类岂不是很⿇烦?这个时候就引⼊了匿名内部类实例2:匿名内部类的基本实现public abstract void eat();}public class Demo {public static void main(String[] args) {Person p = new Person() {public void eat() {System.out.println("eat something");}};p.eat();}}运⾏结果:eat something可以看到,我们直接将抽象类Person中的⽅法在⼤括号中实现了这样便可以省略⼀个类的书写并且,匿名内部类还能⽤于接⼝上实例3:在接⼝上使⽤匿名内部类interface Person {public void eat();}public class Demo {public static void main(String[] args) {Person p = new Person() {public void eat() {System.out.println("eat something");}};p.eat();}}运⾏结果:eat something由上⾯的例⼦可以看出,只要⼀个类是抽象的或是⼀个接⼝,那么其⼦类中的⽅法都可以使⽤匿名内部类来实现最常⽤的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接⼝实例4:Thread类的匿名内部类实现public class Demo {public static void main(String[] args) {Thread t = new Thread() {public void run() {for (int i = 1; i <= 5; i++) {System.out.print(i + " ");}}};t.start();}}运⾏结果:1 2 3 4 5实例5:Runnable接⼝的匿名内部类实现public class Demo {public static void main(String[] args) {Runnable r = new Runnable() {public void run() {for (int i = 1; i <= 5; i++) {System.out.print(i + " ");}}};Thread t = new Thread(r);t.start();}}运⾏结果:1 2 3 4 5如有疑问请留⾔或者到本站社区交流讨论,感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!。
chapter03-内部类匿名内部类匿名对象

2
类里面的两个重要方法使用说明
1、equals()方法:用于测试某个对象是否同另一个对象相等。它在 Object类中的实现是判断两个对象是否指向同一块内存区域。这 中测试用处不大,因为即使内容相同的对象,内存区域也是不同 的。如果想测试对象是否相等,就需要覆盖此方法,进行更有意 义的比较。
2 、 toString():返回该对象的字符串表示。Object类中的toString() 方法会打印出类名和对象的内存位置。几乎每个类都会覆盖该方 法,以便打印对该对象当前状态的表示。大多数(非全部) toString()方法都遵循如下格式:类名[字段名=值,字段名=值 ...],当然,子类应该定义自己的toString()方法。
7
内部类的几种具体应用
❖1、静态内部类 ❖2、局部内部类 ❖3、匿名内部类
8
匿名对象的使用
❖匿名对象通常使用在以下两种情况: ❖(1)如果对一个对象只需要进行一次方法
调用,那么就可以使用匿名对象。
❖(2)将匿名对象作为实参传递给一个方法 调用。
9
10
6
内部类的例子-使用内部类
如示例代码所示,对于给定的一个外部类实例outerClass,可以直接创建其内部 类实例,语法形式为: OuterClass.InnerClass innerClass = outerClass.new InnerClass(); 成员类不能与外部类重名 。 不能在成员类中定义static字段、方法和类。 成员类不能是接口(interface)。
java匿名内部类底层原理

java匿名内部类底层原理
Java匿名内部类是Java编程语言中的一个特性,允许你在一个方法内部定义一个没有名字的类。
这种类被称为匿名内部类。
匿名内部类的底层原理主要涉及到Java的字节码和内存模型。
下面是一些关键的概念和步骤:
1. 字节码:Java源代码在编译时会被转换成字节码。
字节码是一种平台无关的中间代码,可以在任何安装了Java虚拟机(JVM)的设备上运行。
2. 内存模型:当你在Java中创建对象时,JVM会在堆内存中为这个对象分配空间。
每个对象都包含类信息(即类的元数据)、实例变量和一些用于跟踪和管理的额外信息。
3. 匿名内部类的生成:当你在代码中定义一个匿名内部类时,JVM会做以下几件事情:
字节码生成:编译器会将匿名内部类的定义转换成字节码。
由于这个类没有名字,编译器会为它生成一个独特的类名,通常是基于它所在的方法和代码的位置。
堆内存分配:JVM会在堆内存中为这个匿名内部类对象分配空间。
这个对象会包含这个匿名类的所有实例变量和任何实现的方法。
实例化:当你在代码中创建这个匿名内部类的实例时,JVM会在堆内存中为这个新对象分配空间,并调用其构造函数来初始化这个对象。
4. 垃圾收集:当一个对象不再被引用时,JVM的垃圾收集器会回收这个对象占用的内存。
对于匿名内部类,如果它是局部变量并且它的范围已经结束(例如,方法已经返回),那么这个匿名类的对象和它占用的内存可能会被回收。
需要注意的是,由于JVM的内存管理策略和垃圾收集机制,实际的行为可能会因JVM的实现和运行时的环境而有所不同。
匿名内部类——精选推荐

匿名内部类内部类是指在⼀个外部类的内部再定义⼀个类。
匿名内部类也就是没有名字的内部类。
正因为没有名字,所以匿名内部类只能使⽤⼀次,它通常⽤来简化代码编写。
使⽤匿名内部类的前提条件是必须继承⼀个⽗类或实现⼀个接⼝。
继承抽象类的匿名内部类1abstract class Person {2public abstract void eat();3 }4public class Demo {5public static void main(String[] args) {6 Person p = new Person() {7public void eat() {8 System.out.println("eat something");9 }10 };11 p.eat();12 }13 }------------------------------------------------------------------------------------------------------------------------------------------------------------实现接⼝的匿名内部类1interface Person {2public void eat();3 }4public class Demo {5public static void main(String[] args) {6 Person p = new Person() {7public void eat() {8 System.out.println("eat something");9 }10 };11 p.eat();12 }13 }匿名内部类不能有构造⽅法;匿名内部类不能定义任何静态成员、⽅法和类;匿名内部类不能是public、protected、private、static;只能创建匿名内部类的⼀个实例;⼀个匿名内部类⼀定是在new的后⾯,⽤其隐含实现⼀个接⼝或实现⼀个类;因匿名内部类为局部内部类,所以局部内部类的所有限制都对其⽣效;在匿名类中⽤this时,这个this指的是匿名类本⾝。
内部类之匿名内部类

内部类之匿名内部类•内部类标识符:•每个类会产生一个.class文件,文件名即为类名。
同样,内部类也会产生一个.class文件,但是它的名称却不是内部类的类名,而是有着严格限制:外围类的名字,加上$,再加上内部类名字•匿名内部类•也就是没有名字的内部类,其名称由Java编译器给出,一般是形如:外部类名称$ 匿名类顺序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有构造器。
它通常用来简化代码编写•匿名内部的创建格式:new 父类构造器(参数列表)|实现接口(){//匿名内部类的类体部分}•匿名类分类•匿名类由于是一个new的结果,所以其实可以赋值给一个父类对象。
因此可以分为两种匿名类,成员匿名类和局部匿名类(作为函数参数)。
•使用匿名内部类前提条件•必须继承一个父类或实现一个接口当然也仅能只继承一个父类或者实现接口。
同时它也是没有class关键字,这是因为匿名内部类是直接使用new来生成一个对象的引用。
当然这个引用是隐式•匿名内部类使用的注意事项•1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
同时要实现父类或接口中所有抽象方法,可以改写父类中的方法,添加自定义方法。
•2、匿名内部类因为没有类名,可知匿名内部类中是不能定义构造函数的。
•3、匿名内部类中不能存在任何的静态成员变量和静态方法。
•4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内类生效。
•5、因为在创建匿名内部类的时候,会立即创建它的实例,匿名内部类不能是抽象的,它必须要实现继承的类或者实现接口的类的所有抽象方法。
•6、匿名内部类和外部类有同名变量方法)时,默认访问的是匿名内部类的变量(方法),要访问外部类的变量(方法)则需要加上外部类的类名。
匿名内部类访问外部类成员变量或成员方法必须用static修饰•匿名内部类的使用package com.vg.demo04;//不使用匿名内部类来实现抽象方法abstract class Person{public abstract void eat();}class Child extends Person{public void eat() {System.out.println("eat something");}}public class TestDemoniming {public static void main(String[] args) {Person p = new Child();p.eat();}}package com.vg.demo04;//匿名内部类的基本实现abstract class Person{public abstract void eat();}public class TestDemoniming {public static void main(String[] args) { Person p = new Person() {public void eat() {System.out.println("eat something"); }};p.eat();}}package com.vg.demo04;//在接口上使用匿名内部类interface Person{public abstract void eat();}public class TestDemoniming {public static void main(String[] args) { Person p = new Person() {public void eat() {System.out.println("eat something"); }};p.eat();}}package com.vg.demo04;//Thread类的匿名内部类实现public class TestDemoniming {public static void main(String[] args) { Thread t = new Thread() {public void run () {for(int i = 1;i<=5;i ) {System.out.println(i " ");}}};t.start();}}package com.vg.demo04;//Runnable接口的匿名内部类实现public class TestDemoniming {public static void main(String[] args) { Runnable r = new Runnable() { public void run () {for(int i = 1;i<=5;i ) {System.out.println(i " ");}}};Thread t = new Thread(r);t.start();}}来源:。
Java:匿名类,匿名内部类

Java:匿名类,匿名内部类内部类匿名类⾸发⽇期:2018-03-25内部类:在⼀个类中定义另⼀个类,这样定义的类称为内部类。
【包含内部类的类可以称为内部类的外部类】如果想要通过⼀个类来使⽤另⼀个类,可以定义为内部类。
【⽐如苹果⼿机类,苹果⼿机类中的黄⾦版的是特别定制的】内部类的外部类的成员变量在内部类中仍然有效,内部类中的⽅法也可以调⽤外部类中的⽅法。
【不论是静态还是⾮静态的,内部类都可以直接调⽤外部类中的属性,】内部类的类体中不可以声明类变量和类⽅法。
内部类可以由外部类使⽤外部类中在函数中创建内部类对象来使⽤,,如果内部类的权限是⾮私有,⾮静态的,就可以在外部其他程序中被访问到,就可以通过创建外部类对象完成,;如果内部类是静态的,⾮私有的,静态成员可以直接类名调⽤,⾮静态成员通过创建外部类对象使⽤。
class Outer{int a=5;static int b=6;void show() {System.out.println("hello world");}class Inner{void use() {System.out.println(a);//5System.out.println(b);//6show();//hello world}}void create() {new Inner().use();}}public class Demo {public static void main(String[] args) {new Outer().create();Outer.Inner oi=new Outer().new Inner();e();}}补充:内部类的字节码⽂件会不⼀样。
会变成外部类名$内部类名将内部类定义在了局部位置上。
可以访问外部类的所有成员局部内部类不能访问所在局部的局部变量(本来他们⽣命周期不同,本来内部类对象的空间没有消失,对象⽣命长)若需访问,加final修饰变量即可,加final变成常量。
匿名内部类定义方法

匿名内部类定义方法嘿,朋友们!今天咱来聊聊匿名内部类定义方法这档子事儿。
啥是匿名内部类呀?简单来说,就像是一个隐藏在代码世界里的小神秘。
它没有名字,但却有着独特的作用。
想象一下啊,你在写代码的时候,突然需要一个类来做一件特定的小事儿,就这一下子的事儿,专门给它起个名字好像有点太麻烦了。
这时候,匿名内部类就闪亮登场啦!比如说,你有个接口,里面有个方法需要实现。
通常呢,你得专门写个类去实现它,然后再创建这个类的对象来用。
但有了匿名内部类,你可以直接在使用的地方就把这个类定义了,并且同时创建对象,多方便快捷呀!就好像你饿了,不用大老远跑去餐馆,而是直接在眼前就变出了美食。
它的定义方法其实也不难理解。
你就在需要的地方,直接用 new 关键字,后面跟上要实现的接口或者要继承的父类,然后在大括号里面写实现的方法或者重写的方法。
嘿,就这么简单粗暴!咱举个例子呗,比如说有个动物接口,里面有个叫叫的方法。
那你就可以在使用的地方这样写:new 动物接口 {public void 叫() {System.out.println("汪汪汪");}}你看,这就瞬间有了一个实现了动物接口,并且会“汪汪汪”叫的类啦!神奇不神奇?它的好处可不少呢!不仅让代码看起来更简洁,而且还能让你的代码更贴近具体的业务需求。
不用到处去找那个专门的实现类,就在当下,一下子就搞定了。
而且哦,匿名内部类还能访问外部类的变量呢,就像一个贴心的小助手,知道你需要什么,随时给你提供帮助。
当然啦,用匿名内部类也得注意一些事儿。
比如说,它可不能定义构造方法哦,毕竟它都没名字,怎么定义构造方法呢?还有啊,它的作用范围也比较有限,可别指望它能做太多太复杂的事儿。
总之呢,匿名内部类就像是代码世界里的一把小巧而锋利的剑,用好了能让你的代码如虎添翼,不好好掌握可就浪费啦!大家可得好好琢磨琢磨,把它用得恰到好处呀!怎么样,是不是对匿名内部类定义方法有了更深的了解呢?赶紧去试试吧!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.new父类构造器(参数列表)|实现接口()
2.{
3.//匿名内部类的类体部分
4.}
从上面定义可以看出,匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
关于匿名内部类还有如下两条规则:
1)匿名内部类不能是抽象类,因为系统在创建匿名内部类的时候,会立即创建内部类的对象。
因此不允许将匿名内部类
定义成抽象类。
2)匿名内部类不等定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,
通过实例初始化块来完成构造器需要完成的事情。
最常用的创建匿名内部类的方式是需要创建某个接口类型的对象,如下程序所示:[java]view plaincopy
1.interface Product{
2.public double getPrice();
3.public String getName();
4.}
5.public class TestAnonymous{
6.public void test(Product p){
7. System.out.println("购买了一个"+p.getName()+",花掉了
"+p.getPrice());
8. }
9.public static void main(String[]args){
10. TestAnonymous ta = new TestAnonymous();
11. ta.test(new Product(){
12.public double getPrice(){
13.return567;
14. }
15.public String getName(){
16.return"AGP显卡";
17. }
18. });
19. }
20.}
上面程序中的TestAnonymous类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口,
无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法---如果这个Product接口实现类需要重复
使用,则应该经该实现类定义一个独立类;如果这个Product接口实现类只需一次使用,则可采用上面程序中的方式,定义
一个匿名内部类。
正如上面程序中看到,定义匿名类不需要class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。
上面
粗体字代码部分就是匿名类的类体部分。
由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。
对于上面创建Product实现类对象的代码,可以拆分成如下代码:
[java]view plaincopy
1.class AnonymousProduct implements Product{
2.public double getPrice(){
3.return567;
4. }
5.public String getName(){
6.return"AGP显卡";
7. }
8. }
9. ta.test(new AnonymousProduct());
当通过实现接口来创建匿名内部类时,匿名内部类也不能显示创建构造器,因此匿名内部类只有一个隐式的无参数构造
器,故new接口名后的括号里不能传入参数值。
但如果通过继承父类来创建匿名内部类是,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的形参
列表。
[c-sharp]view plaincopy
1.abstract class Device{
2.private String name;
3.public Device(){
4. }
5.public Device(String name){
= name;
7. }
8.public abstract double getPrice();
9.//此处省略了name属性的setter和getter方法
10. }
11.public class AnonymousInner{
12.public void test(Device d){
13. System.out.println("购买了一个"+d.getName()+",花掉了"+d.getPrice());
14. }
15.public static void main(String[] args){
16. AnonymousInner ai = new AnonymousInner();
17.//调用有参数的构造器创建Device匿名实现类的对象
18. ai.test(new Device("电子示波器"){
19.public double getPrice(){
20.return 67;
21. }
22. });
23.//调用无参数的构造器创建Device匿名实现类的对象
24. Device d = new Device(){
25.//初始化块
27. System.out.println("匿名内部类的初始化块...");
28. }
29.//实现抽象方法
30.public double getPrice(){
31.return 56;
32. }
33.public Sting getName(){
34.return"键盘";
35. }
36. };
37. ai.test(d);
38. }
39. }
上面程序创建了一个抽象父类Device,这个抽象父类里包含两个构造器:一个无参数的,一个有参数的。
当创建以Device
为父类的匿名内部类时,即可以传入参数(如上面程序中第一段粗体字部分),也可以不传入参数(如上面程序中第二段粗体
字部分)。
当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。
如果有需要,也可以重写父类中的普通方法,如上面
程序的第二段粗体字代码部分,匿名内部类重写了抽象父类Device类的getName方法,其中getName方法并不是抽象方法。
如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量,
否则系统将报错。
[java]view plaincopy
1.interface A{
2.void test();
3. }
4.public class TestA{
5.public static void main(Strign[] args){
6.int age = 0;
7. A a = new A(){
8.public void test(){
9.//下面语句将提示错误:匿名内部类内访问局部变量必须使用final修饰
10. System.out.println(age);
12. };
13. }
14. }
上面程序中粗体子代码是匿名内部类访问了外部类的局部变量,由于age变量没有使用final修饰符修饰,所以粗体字代码将
引起编译异常。