Anonymous Inner 类 实际上不是子类吗?
Aren't Anonymous Inner Classes actually subclasses?
假设 A 是自定义的 class,并考虑以下匿名内部 class 的声明:
A Obj = new A() {
@Override
public String toString() {
return "Hello!";
}
}
在这种情况下,Obj 是匿名内部 class 的实例,其 toString 方法已被覆盖。由于它是用类型 A 声明的,所以匿名 class 必须是 A 的子 class。那么,为什么这个 class 不称为匿名子 class 而不是匿名内部 class? 'inner' 从哪里来?
是的,obj
是 A
的子 class 的实例。您可以通过调用 obj.getClass().getSuperclass()
:
来验证 superclass
打印出如下内容:
class Whosebug.Test //obj.getClass()
class Whosebug.A //obj.getClass().getSuperclass()
So then, why isn't this class called an Anonymous Subclass instead of an anonymous inner class?
那些只是语义。这是一个名字。然而,可能有很多原因,其中之一是匿名 classes 可以直接实现接口:
Runnable r = new Runnable() {
public void run() {}
}
这不是任何对象的子class(但是对象,但不是对象的子class...),但它也是匿名的class .
子class和内class是匿名class的两个不同方面。由于语法原因,匿名 class 显然是命名 class 的子 class,因此 inner 方面与分类更相关.
Java class是这样的分类1:
如您所见,匿名 class 是内部嵌套 class。
分类未指定 class 是子 class、基础 class 还是独立 class。任何类别的 类 都可以是子 class 或基础 class。由于 ,匿名 class 可以从接口定义,在这种情况下它根本不是子 class。
1) .
末尾更大层次结构的摘录
Why isn't this class called an Anonymous Subclass instead of an anonymous inner class?
因为(通常)匿名内部 class 不一定是 subclasses1。匿名内部 class 可以扩展接口而不是 class.
因为"subclass-ness"在大多数我们谈论匿名内部的上下文中2不重要classes.
因为人是懒惰的3而"Anonymous Inner Subclasses"多了一个音节。或者换句话说,人们有一种自然倾向优化他们的演讲和写作模式。
因为...惯例。
Where does the 'inner' come from?
Inner 在 Java 中具有技术意义。这意味着两件事。
- 表示class是在另一个class中声明的。
- 表示允许class引用封闭class.
实例的this
请参阅@Andreas 的回答中的分类法。
历史脚注。
其实官方术语是AnonymousClass。事实上,Sun 在 Java 1.1 中使用术语 "Anonymous Class" 而不是 "Anonymous Inner Class",当时该结构被添加到语言中。例如,Java 1.1.4 发行说明中的 "Inner Class Specification" 在大多数情况下将它们称为 "Anonymous Classes" ...。
我怀疑发生的事情是 Sun 早期的演示文稿或论文中存在一些不一致,并且许多非 Sun 作者在他们的作品中锁定了 "anonymous inner class" 版本。 Sun 团队试图通过使用官方 Java 语言规范和教程中的 "Anonymous Class" 悄悄纠正这个问题。但为时已晚了。书在书店,文章在网上。
1 - 除了微不足道的意义。每个不是 Object 的 class 必须是 some class.
的子class
2 - 同样,您通常会说 "I am taking the dog for a walk",而不是 "I am taking the black Labrador for a walk"。
3 - 在这种情况下,"good lazy".
回答你的问题标题,是的,他们是。匿名内部 classes 实际上是 subclasses.
"Since it was declared with type A, the anonymous class, [Obj], must be a subclass of A."
干得好。 :)
无论如何,回答为什么 "inner" 在那里:如果你在另一个 class 中声明一个匿名 class (并且匿名 class 不是静态声明的,下面有更多内容)然后它将能够像内部 class 一样访问其周围的 class 。例如:
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
的底层 class 和 class RegularInner
都可以访问 Outer
的字段,而其他 instance-specific 属于 Outer
的内容。这就是为什么匿名 class 有时可能被称为 "inner" class.
任何内部 class 的实例都需要使用外部 class 的实例来创建以备份它,否则它将不知道哪个 object,(不是class),属于.
静态垃圾
如果匿名 class 被声明为 static
,它将无法访问其周围 class 的内容并且不会是 "inner" class(相反,它将是一个匿名 "nested" class)。
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);
}
}
请记住,匿名 class 可以是 "inner" 或 "nested"。因此,在笼统地谈论它们时,只需说 "anonymous class"。 (匿名内部classes是一种匿名class)。另外,请务必阅读评论,因为他们给出了大部分解释。
有什么问题吗? :)
假设 A 是自定义的 class,并考虑以下匿名内部 class 的声明:
A Obj = new A() {
@Override
public String toString() {
return "Hello!";
}
}
在这种情况下,Obj 是匿名内部 class 的实例,其 toString 方法已被覆盖。由于它是用类型 A 声明的,所以匿名 class 必须是 A 的子 class。那么,为什么这个 class 不称为匿名子 class 而不是匿名内部 class? 'inner' 从哪里来?
是的,obj
是 A
的子 class 的实例。您可以通过调用 obj.getClass().getSuperclass()
:
打印出如下内容:
class Whosebug.Test //obj.getClass()
class Whosebug.A //obj.getClass().getSuperclass()
So then, why isn't this class called an Anonymous Subclass instead of an anonymous inner class?
那些只是语义。这是一个名字。然而,可能有很多原因,其中之一是匿名 classes 可以直接实现接口:
Runnable r = new Runnable() {
public void run() {}
}
这不是任何对象的子class(但是对象,但不是对象的子class...),但它也是匿名的class .
子class和内class是匿名class的两个不同方面。由于语法原因,匿名 class 显然是命名 class 的子 class,因此 inner 方面与分类更相关.
Java class是这样的分类1:
如您所见,匿名 class 是内部嵌套 class。
分类未指定 class 是子 class、基础 class 还是独立 class。任何类别的 类 都可以是子 class 或基础 class。由于
1)
Why isn't this class called an Anonymous Subclass instead of an anonymous inner class?
因为(通常)匿名内部 class 不一定是 subclasses1。匿名内部 class 可以扩展接口而不是 class.
因为"subclass-ness"在大多数我们谈论匿名内部的上下文中2不重要classes.
因为人是懒惰的3而"Anonymous Inner Subclasses"多了一个音节。或者换句话说,人们有一种自然倾向优化他们的演讲和写作模式。
因为...惯例。
Where does the 'inner' come from?
Inner 在 Java 中具有技术意义。这意味着两件事。
- 表示class是在另一个class中声明的。
- 表示允许class引用封闭class. 实例的
this
请参阅@Andreas 的回答中的分类法。
历史脚注。
其实官方术语是AnonymousClass。事实上,Sun 在 Java 1.1 中使用术语 "Anonymous Class" 而不是 "Anonymous Inner Class",当时该结构被添加到语言中。例如,Java 1.1.4 发行说明中的 "Inner Class Specification" 在大多数情况下将它们称为 "Anonymous Classes" ...。
我怀疑发生的事情是 Sun 早期的演示文稿或论文中存在一些不一致,并且许多非 Sun 作者在他们的作品中锁定了 "anonymous inner class" 版本。 Sun 团队试图通过使用官方 Java 语言规范和教程中的 "Anonymous Class" 悄悄纠正这个问题。但为时已晚了。书在书店,文章在网上。
1 - 除了微不足道的意义。每个不是 Object 的 class 必须是 some class.
的子class2 - 同样,您通常会说 "I am taking the dog for a walk",而不是 "I am taking the black Labrador for a walk"。
3 - 在这种情况下,"good lazy".
回答你的问题标题,是的,他们是。匿名内部 classes 实际上是 subclasses.
"Since it was declared with type A, the anonymous class, [Obj], must be a subclass of A."
干得好。 :)
无论如何,回答为什么 "inner" 在那里:如果你在另一个 class 中声明一个匿名 class (并且匿名 class 不是静态声明的,下面有更多内容)然后它将能够像内部 class 一样访问其周围的 class 。例如:
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
的底层 class 和 class RegularInner
都可以访问 Outer
的字段,而其他 instance-specific 属于 Outer
的内容。这就是为什么匿名 class 有时可能被称为 "inner" class.
任何内部 class 的实例都需要使用外部 class 的实例来创建以备份它,否则它将不知道哪个 object,(不是class),属于.
静态垃圾
如果匿名 class 被声明为 static
,它将无法访问其周围 class 的内容并且不会是 "inner" class(相反,它将是一个匿名 "nested" class)。
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);
}
}
请记住,匿名 class 可以是 "inner" 或 "nested"。因此,在笼统地谈论它们时,只需说 "anonymous class"。 (匿名内部classes是一种匿名class)。另外,请务必阅读评论,因为他们给出了大部分解释。
有什么问题吗? :)