有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java实际上不是匿名内部类的子类吗?

假定A是自定义类,并考虑下面的匿名内部类声明:

A Obj = new A() {
    @Override
    public String toString() {
        return "Hello!";
    }
}

在这个场景中,Obj是一个匿名内部类的实例,其toString方法已被重写。因为它是用类型A声明的,所以匿名类必须是A的子类。那么,为什么这个类不称为匿名子类而不是匿名内部类呢?“内在”来自哪里


共 (4) 个答案

  1. # 1 楼答案

    子类和内部类是匿名类的两个不同方面。由于语法的原因,匿名类显然是命名类的子类,因此内部方面与分类更相关

    Java类是这样的类别1

    如您所见,匿名类是一个内部嵌套类

    分类没有指定该类是子类、基类还是独立类。任何类别的类都可以是子类或基类。作为ernest_k mentioned in another answer,匿名类可以从接口定义,在这种情况下,它根本不是子类

    1)摘自this other answer结尾的更大层次结构

  2. # 2 楼答案

    Why isn't this class called an Anonymous Subclass instead of an anonymous inner class?

    • 因为(通常)匿名内部类不一定是子类1。匿名内部类可以扩展接口而不是类

    • 因为在我们谈论匿名内部类的大多数上下文中,“子类性”并不重要

    • 因为人类是懒惰的,3“匿名内部子类”是一个额外的音节。或者换句话说,人们有一种自然的倾向,即优化自己的语言和写作模式

    • 因为。。。惯例

    Where does the 'inner' come from?

    Inner在Java中具有技术意义。这意味着两件事

    • 这意味着该类是在另一个类中声明的
    • 这意味着允许类引用封闭类的实例的this

    在@Andreas的回答中可以看到很好的分类法


    历史脚注

    事实上,官方术语是匿名类。事实上,早在Java1.1中将构造添加到语言中时,Sun就使用了术语“匿名类”而不是“匿名内部类”。例如,Java 1.1.4发行说明中的"Inner Class Specification"将它们称为“匿名类”。。。大多数时候

    我怀疑发生的事情是,在早期的Sun演示或论文中存在一些不一致之处,不同的非Sun作者在他们的作品中抓住了“匿名内部阶级”的版本。Sun团队试图通过在官方Java语言规范和教程中使用“匿名类”来悄悄地纠正这一点。但为时已晚。书在书店里,文章在网上


    1-除了琐碎的意义。每一个不是Object的类都必须是某个类的子类

    2-同样,你通常会说“我带着狗散步”,而不是“我带着黑色拉布拉多犬散步”

    3-在这种情况下,“好懒”

  3. # 3 楼答案

    是的,objA子类的一个实例。您可以通过调用obj.getClass().getSuperclass()来验证超类:

    它打印出如下内容:

    class stackoverflow.Test$1 //obj.getClass()
    class stackoverflow.A //obj.getClass().getSuperclass()
    

    So then, why isn't this class called an Anonymous Subclass instead of an anonymous inner class?

    这些只是语义学。这是一个名字。然而,可能有很多原因,其中之一是匿名类可以直接实现接口:

    Runnable r = new Runnable() {
        public void run() {}
    }
    

    这不是任何东西的子类(但对象,但什么不是对象的子类…),但它也是一个匿名类

  4. # 4 楼答案

    回答你问题的标题,是的,它们是。匿名内部类实际上是子类

    "Since it was declared with type A, the anonymous class, [Obj], must be a subclass of A."

    干得好。:)

    无论如何,要回答“内部”存在的原因:如果在另一个类中声明一个匿名类(而匿名类不是静态声明的,下面将详细介绍),那么它将能够像内部类一样访问其周围的类。例如:

    public class Outer {
        private final int someRandomValue = 4;
    
        public final Object anonymousInnerInstance = new Object() {
            @Override
            public String toString() {
                // Notice how this class has access to a field declared inside a different
                // class. More specifically, this anonymous class can access someRandomValue,
                // even though someRandomValue belongs to the class, Outer.
                return "Anonymous Inner Class: " + someRandomValue;
            }
        };
    
        public class RegularInner {
            @Override
            public String toString() {
                // This regular inner class is inside Outer, (just like the anonymous class),
                // and can access any of Outer's fields (amongst Outer's other things).
                return "Regular Inner Class: " + someRandomValue;
            }
        }
    
        public final RegularInner regularInnerInstance = new RegularInner();
    
        public static void main(String[] args) {
            Outer outerInstance = new Outer();
            System.out.println(outerInstance.anonymousInnerInstance);
            System.out.println(outerInstance.regularInnerInstance);
    
            // By the way, you can make new RegularInner instances off of our Outer
            // instance:
            RegularInner newInnerInstance = outerInstance.new RegularInner();
            // When you write "outerInstance.new SomeClass()" you're saying:
            // "I'd like to initialize my 'SomeClass' object with 'outerInstance',
            // as its container." This effectively means that any variables that
            // belong to Outer that your SomeClass needs to access, it will access
            // from the Outer instance you gave it.
        }
    }
    

    因此,anonymousInnerInstance的底层类和类RegularInner都可以访问Outer的字段,以及属于Outer的其他特定于实例的内容。这就是为什么匿名类有时可能被称为“内部”类

    任何内部类的实例都需要创建一个外部类的实例来备份,否则它就不知道它属于哪个对象(不是类)


    静态垃圾

    如果一个匿名类被声明为static,它将无法访问其周围类的内容,也不会是一个“内部”类(而是一个匿名的“嵌套”类)

    public class Outer {
        private final int someRandomValue = 4;
    
        public static final Object anonymousStaticInstance = new Object() {
            @Override
            public String toString() {
                // someRandomValue belongs to an INSTANCE of Outer. (So each Outer object you
                // have has its own someRandomValue). Since this anonymous class
                // is now static, it is no longer tied to an instance of Outer. It doesn't have
                // an Outer object that it can read "someRandomValue" from. The same goes for
                // RegularStatic, below.
                return "Anonymous Inner Class: " + someRandomValue;
            }
        };
    
        public static class RegularStatic {
            @Override
            public String toString() {
                return "Regular Inner Class: " + someRandomValue;
            }
        }
    
        public final RegularStatic regularInnerInstance = new RegularStatic();
    
        public static void main(String[] args) {
            Outer outerInstance = new Outer();
            System.out.println(outerInstance.anonymousStaticInstance);// Java warns you here and
            // tells you to access anonymousStaticInstance statically. This is because
            // anonymousStaticInstance no longer belongs to any given instance of Outer.
            // There is only one anonymousStaticInstance, that "belongs" to the class Outer,
            // rather than multiple anonymousInnerInstances which each belong to an instance
            // of Outer.
            System.out.println(outerInstance.regularInnerInstance);
        }
    }
    

    请记住,匿名类可以是“内部的”“嵌套的”。所以,当一般地谈论它们时,只需说“匿名类”。(匿名内部类是一种匿名类)。此外,一定要阅读评论,因为他们给出了大部分解释

    有问题吗?:)