- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个抽象类和它的具体子类,当我创建子类的对象时它会自动调用 super 构造函数。 JVM 是否在内部创建抽象类的对象?
public abstract class MyAbstractClass {
public MyAbstractClass() {
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
public static void main(String[] args) {
new ConcreteClass();
}
}
那么在 JVM 中构造函数如何在没有对象的情况下存在? (在抽象类的情况下)
构造函数在创建对象后执行然后不创建抽象类的对象默认构造函数如何执行? (这在 Java Doc 中提到)
最佳答案
Is it true that you can't instantiate abstract class?
是的。
Is JVM internally create object of abstract class ?
不,但这是一个常见的误解(这并不是一种不合理的方式;像 JavaScript 这样的原型(prototype)语言就是这样做的)。
JVM 创建一个 对象,它属于您创建的类(在您的例子中是ConcreteClass
)。它从其父类(super class) (MyAbstractClass
) 和子类 (ConcreteClass
) 获得了一个对象的某些方面,但只有一个对象。
对象是其所有部分的集合,包括看似同名的部分,例如被子类覆盖的父类(super class)方法。事实上,这些方法具有不同的完全限定名称并且不会相互冲突,这就是为什么可以调用父类(super class)版本的重写方法的原因。
那么如果它只是一个对象,为什么你会看到对 MyAbstractClass
的构造函数的调用?在我们回答这个问题之前,我需要提一下 Java 编译器正在做的一些您在源代码中看不到的事情:
它正在为 ConcreteClass
创建默认构造函数。
在该构造函数中,它调用了 MyAbstractClass
构造函数。
为了彻底:在 MyAbstractClass
构造函数中,它添加了对父类(super class)的 (Object
) 构造函数的调用,因为没有 super( ...)
在 MyAbstractClass
构造函数中编写的调用。
下面是代码的样子,其中包含 Java 编译器为您填充的位:
public abstract class MyAbstractClass {
public MyAbstractClass() {
super(); // <== The Java compiler adds this call to Object's constructor (#3 in the list above)
System.out.println("abstract default constructor");
}
}
public class ConcreteClass extends MyAbstractClass{
ConcreteClass() { // <== The Java compiler adds this default constuctor (#1 in the list above)
super(); // <== Which calls the superclass's (MyAbstractClass's) constructor (#2 in the list above)
}
public static void main(String[] args) {
new ConcreteClass();
}
}
好吧,让开这个问题,让我们谈谈一点 TheLostMind在评论中非常有用地提到:构造函数不创建对象,它们初始化它们。 JVM 创建对象,然后根据需要针对该对象运行尽可能多的构造函数(它们实际上应该称为初始化器),以便为每个父类(super class)提供初始化它的部分的机会对象的。
所以在该代码中,发生了什么(您可以在调试器中逐步完成它以完全理解它)是:
JVM 创建一个对象
ConcreteClass
构造函数被调用
构造函数做的第一件事是调用其父类(super class)的构造函数,在本例中是MyAbstractClass
的构造函数。 (请注意,这是绝对要求:Java 编译器不允许您在父类(super class)构造函数调用之前在构造函数本身中包含任何逻辑。)
构造函数做的第一件事是调用其父类(super class)的构造函数(Object
)
当 Object
构造函数返回时,MyAbstractClass
构造函数的其余部分运行
当 MyAbtractClass
构造函数返回时,ConcreteClass
构造函数的其余部分运行
对象作为 new ConcreteClass()
表达式的结果返回。
请注意,如果存在带有初始值设定项的实例字段,上述内容将变得更加复杂。有关完整详细信息,请参阅 JLS 和 JVM 规范。
关于java - JVM 是否在内部实例化抽象类的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30125552/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!