`
ZangXT
  • 浏览: 116493 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java中匿名内部类的构造方法调用

阅读更多

    

     与人讨论匿名内部类的构造方法问题,自己写代码看看原理到底是什么样子的。因为类是匿名的,所以就无从创建一个同名的构造方法了。但是可以直接调用父类的构造方法。测试代码如下:

 

package testtest;

public class Main {

    public static void main(String[] args) {
        InnerTest inner = new InnerTest();
        Test t = inner.get(3);
        System.out.println(t.getI());
    }
}

class Test {

    private int i;

    public Test(int i) {
        this.i = i;
    }

    public int getI() {
        return i;
    }
}

class InnerTest {

    public Test get(int x) {
        return new Test(x) {

            @Override
            public int getI() {
                return super.getI() * 10;
            }
        };
    }
}

编译之后得到4个class文件:Test.class,InnerTest.class,InnerTest$1.class以及Main.class。容易看出来,Main.class是测试类的class文件,Test.class是超类Test的class文件,InnerTest.class是InnerTest 的class文件,最值得关注的就是匿名内部类的class文件InnerTest$1.class。

首先javap -c InnerTest$1

 

Compiled from "Main.java"
class testtest.InnerTest$1 extends testtest.Test{
final testtest.InnerTest this$0;

testtest.InnerTest$1(testtest.InnerTest, int);
  Code:
   0:	aload_0
   1:	aload_1
   2:	putfield	#1; //Field this$0:Ltesttest/InnerTest;
   5:	aload_0
   6:	iload_2
   7:	invokespecial	#2; //Method testtest/Test."<init>〈init〉":(I)V
   10:	return

public int getI();
  Code:
   0:	aload_0
   1:	invokespecial	#3; //Method testtest/Test.getI:()I
   4:	bipush	10
   6:	imul
   7:	ireturn

}

</init>

很明显,虽然我们看来是匿名内部类,但编译的时候给这个类指定了名字

InnerTest$1,而且看出来是继承自Test:

class testtest.InnerTest$1 extends testtest.Test

而且在这个类有构造方法: 

testtest.InnerTest$1(testtest.InnerTest, int);

这里也很容易理解,两个参数,一个是匿名内部类的外部类引用直接传了进来,这也是我们能在内部类中直接访问外部类成员的实现原理。另外一个就是int类型的参数了。也就是说其实编译器自动的给我们添加了带参数的构造方法。继续往下看: 
7: invokespecial #2; //Method testtest/Test."<init>":(I)V
这就是调用父类的构造方法了 。
接下来 ,我们 只要看 InnerTest中 get方法 的 实现就可以了 :

Compiled from "Main.java"
class testtest.InnerTest extends java.lang.Object{
testtest.InnerTest();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."<init>〈init〉":()V
   4:	return

public testtest.Test get(int);
  Code:
   0:	new	#2; //class testtest/InnerTest$1
   3:	dup
   4:	aload_0
   5:	iload_1
   6:	invokespecial	#3; //Method testtest/InnerTest$1."<init>〈init〉":(Ltesttest/InnerTest;I)V
   9:	areturn

}
</init></init>


到这里一切都清楚了,InnerTest中对待匿名内部类和对待普通类一样,

先是

0:	new	#2; //class testtest/InnerTest$1

然后调用其构造方法:

6: invokespecial #3; //Method testtest/InnerTest$1."〈init〉":(Ltesttest/InnerTest;I)V


<init></init><init>OK,一切都清楚了 。<br></init>

分享到:
评论

相关推荐

    使用Java匿名内部类实现一个简单的线程池.txt

    这段代码实现了一个简单的线程池ExecutorService,其中使用了Java的匿名内部类。...这个简单的示例代码展示了如何使用Java匿名内部类来实现一个线程池的简单功能,方便了对多线程任务的管理和执行。

    Java开发技术大全(500个源代码).

    anonymousInner.java 匿名内部类 base.java 定义一个基类 BaseColors.java 一个简单的接口 basePoint.java 一个测试用的基类 Colorable.java 一个子接口 ColoredPoint.java 一个测试用子类 common.java 一个...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.9.4 在构造方法中调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    7.9.4 在构造方法中调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解Java方法 191 7.12 习题 192 第8章 Java中的包(Package)...

    java内部学习笔记.docx

    2.14 Java系统API方法调用 14 2.15二进制基础 14 2.16 Java基础其他注意事项 14 面向对象 16 3.1类 16 3.2对象 16 3.3包 16 3.4方法及其调用 17 3.5引用 17 3.6访问控制(封装) 17 3.7构造器 17 3.8 super()、super...

    java初学者必看

    8.2 super构造方法调用 8.3 封装和继承 8.4 使用继承 8.4.1 Object类 8.4.2 定义equals方法 8.5 关于设计好继承的几点建议 8.6 实例:一卡通类的继承 8.6.1 构造方法 8.6.2 setter方法 8.6.3 getter方法 ...

    Java经典编程源码基础例程300.zip

    实例068 匿名内部类的简单应用 104 实例069 静态内部类的简单应用 105 实例070 实例化Class类的几种方式 107 实例071 查看类的声明 108 实例072 查看类的成员 110 实例073 查看内部类信息 112 实例074 动态设置类的...

    JAVA面试题最全集

    一个“.java”原文件中是否可以包括多个类(不是内部类)? 53.掌握内部类和接口的概念 54.StringTokenizer类的使用 55.数据结构,如何遍历List中的元素? 如果要按照键值保存或者访问数据,使用什么数据结构? ...

    JAVA面向对象详细资料

    Java面向对象 1 1 学习方法与要求 1 2 面向对象语言与面向过程语言的区别 7 3 面向对象?...41.2 匿名内部类 70 41.3 成员内部类 71 41.4 静态内部类 72 41.5 局部内部类 73 42 作业 :商超案例,以OOP重构 73

    疯狂JAVA讲义

    6.7.5 匿名内部类 212 6.7.6 闭包(Closure)和回调 215 6.8 枚举类 217 6.8.1 手动实现枚举类 217 6.8.2 枚举类入门 219 6.8.3 枚举类的属性、方法和构造器 220 6.8.4 实现接口的枚举类 223 6.8.5 包含抽象...

    JAVA语言程序设计【高清版】.pdf

    90 5.7.2 接口的定义 91 5.7.3 接口的实现 91 5.8 Java包 94 5.8.1 Java包的概念 94 5.8.2 import语句 95 5.9 内部类 97 5.9.1 内部类的概念 97 5.9.2 匿名类 99 习题 100 第6章 数组、容器和字符...

    【05-面向对象(下)】

    •在java类里只能包含Field,方法,构造器,初始化块,内部类(接口、枚举)等5种成员。 用static修饰的类成员属 于类成员,类Field既可通过类来访问,也可以通过类的对象来访问。当通过对象来访问类属性时,系统会在底...

    java 面试题 总结

    它是基于Java的远程方法调用(RMI)技术的,所以EJB可以被远程访问(跨进程、跨计算机)。但EJB必须被布署在诸如Webspere、WebLogic这样的容器中,EJB客户从不直接访问真正的EJB组件,而是通过其容器访问。EJB容器是...

    Java面试宝典2017.zip

    1、一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 7 2、Java有没有goto? 7 3、说说&和&&的区别。 8 4、在JAVA中如何跳出当前的多重嵌套循环? 8 5、switch语句能否作用在byte上,能否作用在...

    corejava培训文档

    匿名内部类 7.12. 集合 7.12.1. 集合接口类层次 7.12.2. 集合类层次 7.12.3. 五个最常用的集合类之间的区别和联系 7.12.4. 比较 7.13. 反射 8. 七 异常 8.1. 异常的基本概念 8.2. 捕获异常 8.3. ...

    21天学通Java-由浅入深

    240 12.2.1 创建局部内部类 240 12.2.2 在局部内部类中访问外部类成员变量 240 12.2.3 在局部内部类中访问外部类的局部变量 241 12.2.4 静态方法中的局部内部类 243 12.3 静态内部类 244 12.3.1 创建静态内部类 244 ...

    java编程练习题

    要求在第一个构造方法中调用第二个构造方法。该类还有两个重载的move()方法,其中一个无参,在屏幕上输出一行文字: XXX Moving!!(XXX为该动物的名字);另一个需要一个int参数n,在屏幕上输出n次 XXX Moving!! 4,写...

    java基础案例与开发详解案例源码全

    8.1.4 匿名内部类211 8.2 对象包装器213 8.3 装箱和拆箱216 8.4 本章习题218 第9章 9.1 String类220 9.1.1 字符串常量221 9.1.2 字符串对象操作224 9.1.3 字符串对象修改228 9.1.4 类型转换230 9.2 StringBuffer类的...

    java面试宝典

    42、一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 12 43、说出一些常用的类,包,接口,请各举5 个。 12 44、Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类?是否可以...

Global site tag (gtag.js) - Google Analytics