本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看活动链接
过滤Java集合的最佳方法是什么?
在我的一次面试中,有人问我“我们是否可以实例化一个抽象类?”
我的回答是“不,我们不能。” 但是,面试官告诉我“错了,我们可以。”
我对此有些争论。然后他告诉我自己在家尝试一下。
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
在这里,我正在创建类的实例和抽象类的调用方法。有人可以向我解释一下吗?面试中我真的错了吗?
高分回答:
在这里,我正在创建我的课程的实例
不,您不是在这里创建抽象类的实例。而是要创建抽象类的匿名子类的实例。然后,您在抽象类引用上调用指向子类object的方法。
JLS-第15.9.1节中明确列出了此行为:-
如果类实例创建表达式以类主体结尾,则实例化的类是匿名类。然后:
如果T表示一个类,则声明由T命名的类的匿名直接子类。如果T表示的类是最终类,则是编译时错误。
如果T表示接口,则声明实现T命名的接口的Object的匿名直接子类。
无论哪种情况,子类的主体都是在类实例创建表达式中给出的ClassBody。
被实例化的类是匿名子类。
强调我的。
另外,在JLS-第12.5节中,您可以阅读有关对象创建过程的信息。我将在此引用一个声明:-
每当创建新的类实例时,都会为其分配内存空间,并为该类类型中声明的所有实例变量和该类类型的每个超类中声明的所有实例变量(包括所有可能隐藏的实例变量)留出空间。
在返回对新创建对象的引用作为结果之前,使用以下过程处理指示的构造函数以初始化新对象:
您可以在我提供的链接上阅读有关完整过程的信息。
要实际上看到要实例化的类是Anonymous SubClass,您只需要编译两个类。假设您将这些类放在两个不同的文件中:
My.java:
abstract class My {
public void myMethod() {
System.out.print("Abstract");
}
}
Poly.java:
class Poly extends My {
public static void main(String a[]) {
My m = new My() {};
m.myMethod();
}
}
现在,编译两个源文件:
javac My.java Poly.java
现在,在编译源代码的目录中,您将看到以下类文件:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
看到那个班级- Poly$1.class。它是由编译器创建的类文件,与您使用以下代码实例化的匿名子类相对应:
new My() {};
因此,很明显,实例化了一个不同的类。只是,该类仅在编译器编译后才被命名。
通常,将使用以下方式来命名您的类中的所有匿名子类:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
这些数字表示这些匿名类在封闭的类中出现的顺序。
文章翻译自kgs4h5t57thfb6iyuz6dqtun5y-ac4c6men2g7xr2a-stackoverflow-com.translate.goog/questions/1…
作者建议:是可以实现的-创建抽象类的匿名子类的实例
真心感谢帅逼靓女们能看到这里,如果这个文章写得还不错,觉得有点东西的话
求点赞👍 求关注❤️ 求分享👥 对8块腹肌的我来说真的 非常有用!!!
如果本篇博客有任何错误,请批评指教,不胜感激 !❤️❤️❤️❤️