Java 为什么它被称为“A”;“匿名”;内部阶级?

Java 为什么它被称为“A”;“匿名”;内部阶级?,java,Java,就在今天,我需要一种在不同对象之间传递函数的方法。我很快了解到,在Java中不能直接这样做,但可以传递一个wht实例,该实例显然被称为“匿名内部类”,如下所示: 要定义类,请执行以下操作: interface MyCallback { public int execute(int i1, int i2); } 举个例子: MyCallback callback = new MyCallback() { public int execute(int i1, int i2) {

就在今天,我需要一种在不同对象之间传递函数的方法。我很快了解到,在Java中不能直接这样做,但可以传递一个wht实例,该实例显然被称为“匿名内部类”,如下所示:

要定义类,请执行以下操作:

interface MyCallback {
    public int execute(int i1, int i2);
}
举个例子:

MyCallback callback = new MyCallback() {
    public int execute(int i1, int i2) {
        return i1 + i2;
    }
};
并称之为:

int sum = callback.execute(1, 2);  // Sets sum to 3.
很简单。但我不明白的是为什么它被称为“匿名”。我不是给它起了个名字叫MyCallback吗?有名字的东西不能是匿名的,对吗?请帮我摆脱对这个术语的困惑。

匿名类声明自动从类派生 由Java编译器创建实例表达式

MyCallback
是超级类型的名称。匿名子类没有在编译时对开发人员有用的名称

,类似于
MyCallback$1
,但您将无法在源代码中使用它。例如,你不能这样做

MyCallback$1 anonymousClassInstance = ...;

它被称为匿名,只是因为它没有名字


在您的例子中,您提供了一个未命名的
MyCallback
实现(子类)。

不,您说过这是MyCallback()接口的一个实例。使用您提供的方法逻辑实现该接口的类会被动态地指定一个名称,而您不能真正确定或使用该名称。。。所以,是的,就您的源代码而言,它确实是匿名的

(通常,名称是通过在封闭类的名称末尾附加一个数字后缀来构造的——但您无法知道将使用哪个后缀,并且不知道名称对于大多数单词的使用来说是足够匿名的。)

我刚才不是给它起了个名字吗?
MyCallback

不,您没有:名称
MyCallback
属于您在顶部声明的
接口。只能有一个名为
MyCallback
的类型


实现
MyCallback
的类没有程序员可见的名称(因此称为“匿名”)。但是,该类有一个字节码名称,因为JVM要求所有类都有一个名称。通常,此隐藏名称是特定于环境的。编译器选择它的方式不会与其他类的名称冲突。例如,如果您在Windows上使用Oracle的JVM,您可以看到在
.class
文件中生成的匿名类的代码,这些文件的名称中有美元符号和数字。

匿名内部类将是

public class OuterClass
{
   public OuterClass()
   {
       MyCallback annoInnerClass = new MyCallback(){
             public int execute(int i1, int i2)
             {
                return i1 + i2;
             }
       };

        ....
   }
}
我知道Wicket,你知道匿名内部类;)


它被称为匿名,因为您没有提供类实现的名称。它被称为内部类,因为您是在内联中定义的。

但是您不能在源代码中使用它。
实际上,在反射的帮助下,您可以很容易地使用它,但这是另一回事+1@Pshemo我想说的是,不能将其用作变量或返回类型等的声明类型。完全可以将其与反射一起使用。
System.out.println(callback.getClass().getName())将显示类的名称。它类似于
X$1
,其中
X
是调用
new MyCallback
的类的名称(可能不在接口中)。MyCallback是超级类型的名称。--新函数实例化的对象的超类是java.lang.object(sysout of
callback.getClass().getSuperclass.getName()
)。我想你的意思是说MyCallback是接口(类型)。@Fuhrmanator也许我应该说是超级类型。匿名类的类型派生自实例创建表达式中使用的引用类型的名称。如果是接口类型,则匿名类实现该接口。如果是类类型,则匿名类将扩展该类。请尝试打印
回调
的实际类的名称。您可以通过
callback.getClass().getName
获取它,并将其与
MyCallback
@Pshemo我的注释的名称进行比较