与人讨论匿名内部类的构造方法问题,自己写代码看看原理到底是什么样子的。因为类是匿名的,所以就无从创建一个同名的构造方法了。但是可以直接调用父类的构造方法。测试代码如下:
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编程中,匿名内部类主要用于事件处理、回调...
这样,当我们调用 `t.getI()` 时,实际上会执行匿名内部类中重写的方法,返回的是 `super.getI()` 的10倍。 在编译后,匿名内部类会生成一个单独的 `.class` 文件,如 `InnerTest$1.class`,其中包含了匿名内部类的...
`MyThread2`中,匿名内部类直接实现了`Thread`的`run()`方法,而`MyThread3`则创建了一个实现了`Runnable`接口的匿名内部类,然后将其传递给`Thread`构造函数。 匿名内部类的特点: 1. **简洁紧凑**:匿名内部类...
在Java 8中,匿名内部类、Lambda表达式和方法引用是重要的新特性,它们极大地简化了代码,提升了代码的可读性和效率。下面将详细探讨这三个知识点,并结合提供的测试用例进行分析。 1. **匿名内部类**: 匿名内部类...
匿名类一定是内部类,它可以直接使用父类的构造方法来创建对象。 在 Java 中,我们可以使用 throw 关键字来抛出一个 Exception 子类的实例,从而发生异常。异常对象可以调用一些方法来获取或输出异常信息,如 ...
匿名内部类是Java编程语言中一个独特而强大的特性,它允许开发者在不定义单独类的情况下实现接口或继承抽象类。这种类没有名称,通常用于快速实现特定功能或回调机制,尤其是在处理事件监听器时非常常见。匿名内部类...
内部类的构造器可以访问外部类的构造器,但如果内部类不是静态的,则需要调用`super()`来完成对父类构造器的调用。例如: ```java class a0 { class b0 { } } class vvv { class ff extends a0.b0 { ff(a0 kk) ...
以下是关于Java匿名内部类的详细总结: 1. **继承父类的匿名内部类**: 当你需要创建一个类的对象,而这个类只有一个方法需要实现时,可以使用匿名内部类。例如,`abstract class Person` 定义了一个抽象方法 `eat...
还提到了内部类的构造方法以及如何在main方法中进行实例化和调用。 以上所述内容是基于Java内部类概念所展开的知识点,涵盖了Java内部类的基本使用方法、语法结构、编译特性以及常见的编程场景。
本文将深入探讨如何在Java中利用匿名内部类进行双括弧初始化的方法。 首先,让我们理解什么是匿名内部类。匿名内部类是不具有名字的类,通常用于实现接口或继承一个类,并且仅在一个地方使用。它们的定义紧跟在它们...
在Java编程语言中,匿名内部类是一种特殊的类,它没有名称,通常用于简洁地实现某个接口或继承某个类,尤其在只需要单个实例且无需多次复用的情况下。这种设计模式可以大大简化代码,提高可读性。下面我们将深入探讨...
- **局部内部类**:定义在方法、构造器或块中的类,其作用域仅限于该方法、构造器或块。 - **匿名内部类**:没有名称的内部类,通常用于快速实现接口或抽象类的一个简短的、一次性版本。 - **嵌套接口**:虽然...
在本文中,我们将深入探讨Java匿名内部类的写法、作用以及如何在实际应用中使用它们。 ### 一、匿名内部类的写法 创建匿名内部类的基本语法如下: ```java new 父类/接口() { // 匿名内部类的实现部分 } ``` ...
在Java编程语言中,构造方法和匿名对象是两个非常重要的概念,它们对于理解和创建对象起着关键作用。本文将深入探讨这两个主题,并结合实例进行详细解释。 首先,我们来看构造方法。构造方法是一种特殊的方法,它与...
2. 编译器自动为内部类的构造方法添加一个参数,参数的类型是外部类的类型, 在构造方法内部使用这个参数为 1 中添加的成员变量赋值。 3. 在调用内部类的构造函数初始化内部类对象时,会默认传入外部类的引用。 六...
匿名内部类的定义通常紧跟在`new`关键字之后,且不能包含构造方法,也不能有静态成员或方法。它们同样遵循局部内部类的规则,只能在一个作用域内创建一个实例。 反射机制是Java提供的一种强大的工具,它允许程序在...
1. 默认构造方法:如果一个类没有显式定义任何构造方法,Java编译器会提供一个无参的默认构造方法,以供创建对象时使用。 2. 自定义构造方法:如果需要对对象的属性进行特定的初始化,可以自定义构造方法,并在其中...
Java匿名内部类是一种特殊的内部类,它没有类名,不能显示的调用new方法来创建对象。匿名内部类通常用来实现某些特殊的功能,例如在事件处理中,经常使用匿名内部类来实现事件处理器。 在Java中,匿名内部类可以...
在创建内部类对象时,会先调用外部类的构造方法,然后才是内部类的构造方法。 ### 4. 部类与接口 - **实现接口**:内部类可以实现一个或多个接口,遵循Java多实现的规则。 - **部类之间的可见性**:部类之间相互...