我的弟弟在中学当老师,正在给一次考试评分。他问了一个问题:“构造函数的目的是什么?”
所以现在有一些答案,比如“构造器创建了一个对象...”
当然,他希望看到类似“构造函数是在对象实例化之后调用的,并用于初始化对象的成员变量...”(仅举个例子)
问题是,有很多文献都是作者写Java中的构造函数创建对象的,而且一般来说,大多数作者似乎避免详细解释整个过程。
我认为它是这样工作的:
类构造函数被称为new运算符的操作数,因为“构造函数的名称提供了要实例化的类的名称”。(参见http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html)
但在执行此构造函数之前,new运算符会实例化该类(分配内存等)。并将成员变量设置为其默认值。
然后执行构造函数,并初始化成员变量。
在最后一步中,new操作符返回对对象的引用。
但我真的不知道这是否真的正确,以及事情是否按确切的顺序发生。
有没有人知道创建对象的细节?如果你创建一个子类,它是如何工作的?是不是首先创建超类,然后调用它的构造函数,然后以某种方式将子类合并到现有的构造中,然后调用它的构造函数?有人会以某种方式认为构造函数“创建”了一个对象吗?
我真的很期待看到你的答案!
发布于 2013-05-27 00:57:07
血淋淋的细节在Java Language Spec中有所涉及,这里是你每天需要知道的基础知识(下一节继续,我指出了类初始化,当一个类第一次有新的调用它时会发生(也有其他方法发生))。
new为对象分配内存,并将其初始化为0、null、false (取决于类型)。这就是为什么保证所有实例变量都有初始值的原因。
假设new成功,则调用构造函数以允许程序员执行其他初始化/任务。
构造函数做的第一件事是调用父构造函数(super(...))。这在层次结构中一直向上发生,直到到达没有父级的java.lang.Object。
在执行构造函数之前,运行任何实例初始化块,后面是任何具有赋值运算符的实例变量。
如果一个实例变量被标记为final并且有一个赋值运算符,这是一个特殊的情况,如果我没记错的话,这似乎发生在调用super之前(这其中有一些技巧)。
所有这些都是为什么您不应该(隐式或显式地)引用this.method()或将其传递到构造函数之外的原因,因为您将使用一个未完成的对象。
发布于 2013-05-27 01:18:56
据我所知,你的解释是正确的。构造函数背后的主要思想是,您可以强制对象的有效状态。
考虑一个名为"Rational“的类,它有两个属性: numerator (int)和denominator (int),代码如下所示(为简洁起见,我省略了getter和setter)
public class Rational {
private int numerator;
private int denominator;
public Rational(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}
public double getRationalValue() {
return (double) numerator / denominator;
}
public static void main(String[] args) {
Rational oneFourth = new Rational(1, 4);
System.out.println(oneFourth.getRationalValue());
}
}如您所见,我已经编写了一个构造函数,它“要求”分子和分母的值。如果您只有一个默认的构造函数,任何人都可以在不指定分子或分母的情况下创建Rational的实例,如果您没有为int变量指定值,它们将被初始化为零。每个人都知道,如果你除以0,宇宙就会崩溃,所以我们想要避免这种情况。
无论如何,正如您正确解释的那样,构造函数不会生成对象。您应该更多地将它们看作是一种称为“后期构造”的方法。
当涉及到基类时,总是首先调用基类的构造函数。这确保您可以在子类构造函数中访问基类的受保护属性。因为Java中的每个类都继承自Object,所以总是首先调用Object构造函数。
以下代码片段:
public class Base {
protected String baseProperty;
public Base() {
System.out.println("In base constructor");
this.baseProperty = "This gets initialized first";
}
static class Sub extends Base {
private String subProperty;
Sub() {
System.out.println("In sub constructor, baseProperty = " + baseProperty);
}
}
public static void main(String args[]) {
Base base = new Sub();
}
}打印:
基构造器中的
在子构造函数中,baseProperty = This首先被初始化
发布于 2013-05-27 00:54:13
从规范中消除您对new和构造函数角色的疑虑:
Creating Objects
如您所知,类提供了对象的蓝图;您可以从一个类创建一个对象。以下每条取自CreateObjectDemo程序的语句都创建一个对象并将其赋值给一个变量:
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);第一行创建Point类的对象,第二行和第三行分别创建Rectangle类的对象。
这些语句中的每一个都有三个部分(下面将详细讨论):
声明:以粗体显示的代码集是将变量名与对象类型相关联的所有变量声明。
Instantiation:关键字是一个创建对象的Java运算符。
Initialization:新运算符之后是对构造函数的调用,该构造函数初始化新对象。
https://stackoverflow.com/questions/16761408
复制相似问题