`
ZangXT
  • 浏览: 117447 次
  • 性别: 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 匿名内部类

    Java匿名内部类是Java语言中一个独特且强大的特性,它允许我们在不定义单独类的情况下创建对象。这种类没有名字,通常用作一次性实现某个接口或继承某个类的需求。在Java编程中,匿名内部类主要用于事件处理、回调...

    简单谈谈java中匿名内部类构造函数

    这样,当我们调用 `t.getI()` 时,实际上会执行匿名内部类中重写的方法,返回的是 `super.getI()` 的10倍。 在编译后,匿名内部类会生成一个单独的 `.class` 文件,如 `InnerTest$1.class`,其中包含了匿名内部类的...

    Android开发匿名内部类

    `MyThread2`中,匿名内部类直接实现了`Thread`的`run()`方法,而`MyThread3`则创建了一个实现了`Runnable`接口的匿名内部类,然后将其传递给`Thread`构造函数。 匿名内部类的特点: 1. **简洁紧凑**:匿名内部类...

    java8 探讨与分析匿名内部类、lambda表达式、方法引用的底层实现的测试用例

    在Java 8中,匿名内部类、Lambda表达式和方法引用是重要的新特性,它们极大地简化了代码,提升了代码的可读性和效率。下面将详细探讨这三个知识点,并结合提供的测试用例进行分析。 1. **匿名内部类**: 匿名内部类...

    java基础第七章内部类与异常类.doc

    匿名类一定是内部类,它可以直接使用父类的构造方法来创建对象。 在 Java 中,我们可以使用 throw 关键字来抛出一个 Exception 子类的实例,从而发生异常。异常对象可以调用一些方法来获取或输出异常信息,如 ...

    匿名内部类_Anoymous_Inner_

    匿名内部类是Java编程语言中一个独特而强大的特性,它允许开发者在不定义单独类的情况下实现接口或继承抽象类。这种类没有名称,通常用于快速实现特定功能或回调机制,尤其是在处理事件监听器时非常常见。匿名内部类...

    Java内部类总结

    内部类的构造器可以访问外部类的构造器,但如果内部类不是静态的,则需要调用`super()`来完成对父类构造器的调用。例如: ```java class a0 { class b0 { } } class vvv { class ff extends a0.b0 { ff(a0 kk) ...

    java中的匿名内部类详细总结

    以下是关于Java匿名内部类的详细总结: 1. **继承父类的匿名内部类**: 当你需要创建一个类的对象,而这个类只有一个方法需要实现时,可以使用匿名内部类。例如,`abstract class Person` 定义了一个抽象方法 `eat...

    Java内部类.pdf

    还提到了内部类的构造方法以及如何在main方法中进行实例化和调用。 以上所述内容是基于Java内部类概念所展开的知识点,涵盖了Java内部类的基本使用方法、语法结构、编译特性以及常见的编程场景。

    在java中 利用匿名内部类进行较简洁的双括弧初始化的方法

    本文将深入探讨如何在Java中利用匿名内部类进行双括弧初始化的方法。 首先,让我们理解什么是匿名内部类。匿名内部类是不具有名字的类,通常用于实现接口或继承一个类,并且仅在一个地方使用。它们的定义紧跟在它们...

    非常精简的匿名内部类详解.docx

    在Java编程语言中,匿名内部类是一种特殊的类,它没有名称,通常用于简洁地实现某个接口或继承某个类,尤其在只需要单个实例且无需多次复用的情况下。这种设计模式可以大大简化代码,提高可读性。下面我们将深入探讨...

    有关JAVA的内部类的好东西

    - **局部内部类**:定义在方法、构造器或块中的类,其作用域仅限于该方法、构造器或块。 - **匿名内部类**:没有名称的内部类,通常用于快速实现接口或抽象类的一个简短的、一次性版本。 - **嵌套接口**:虽然...

    Java匿名内部类的写法示例

    在本文中,我们将深入探讨Java匿名内部类的写法、作用以及如何在实际应用中使用它们。 ### 一、匿名内部类的写法 创建匿名内部类的基本语法如下: ```java new 父类/接口() { // 匿名内部类的实现部分 } ``` ...

    MLDN魔乐JAVA_05构造方法、匿名对象.rar

    在Java编程语言中,构造方法和匿名对象是两个非常重要的概念,它们对于理解和创建对象起着关键作用。本文将深入探讨这两个主题,并结合实例进行详细解释。 首先,我们来看构造方法。构造方法是一种特殊的方法,它与...

    Java内部类总结,内部类的共同特征,内部类的分类等

    2. 编译器自动为内部类的构造方法添加一个参数,参数的类型是外部类的类型, 在构造方法内部使用这个参数为 1 中添加的成员变量赋值。 3. 在调用内部类的构造函数初始化内部类对象时,会默认传入外部类的引用。 六...

    Java构造方法解析.pdf

    1. 默认构造方法:如果一个类没有显式定义任何构造方法,Java编译器会提供一个无参的默认构造方法,以供创建对象时使用。 2. 自定义构造方法:如果需要对对象的属性进行特定的初始化,可以自定义构造方法,并在其中...

    java匿名内部类实例代码详解

    Java匿名内部类是一种特殊的内部类,它没有类名,不能显示的调用new方法来创建对象。匿名内部类通常用来实现某些特殊的功能,例如在事件处理中,经常使用匿名内部类来实现事件处理器。 在Java中,匿名内部类可以...

    Java内部类总结.pdf

    在创建内部类对象时,会先调用外部类的构造方法,然后才是内部类的构造方法。 ### 4. 部类与接口 - **实现接口**:内部类可以实现一个或多个接口,遵循Java多实现的规则。 - **部类之间的可见性**:部类之间相互...

Global site tag (gtag.js) - Google Analytics