首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >详细介绍Java构造函数

问详细介绍Java构造函数
EN

Stack Overflow用户
提问于 2013-05-27 00:43:42
回答 3查看 919关注 0票数 2

我的弟弟在中学当老师,正在给一次考试评分。他问了一个问题:“构造函数的目的是什么?”

所以现在有一些答案,比如“构造器创建了一个对象...”

当然,他希望看到类似“构造函数是在对象实例化之后调用的,并用于初始化对象的成员变量...”(仅举个例子)

问题是,有很多文献都是作者写Java中的构造函数创建对象的,而且一般来说,大多数作者似乎避免详细解释整个过程。

我认为它是这样工作的:

类构造函数被称为new运算符的操作数,因为“构造函数的名称提供了要实例化的类的名称”。(参见http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html)

但在执行此构造函数之前,new运算符会实例化该类(分配内存等)。并将成员变量设置为其默认值。

然后执行构造函数,并初始化成员变量。

在最后一步中,new操作符返回对对象的引用。

但我真的不知道这是否真的正确,以及事情是否按确切的顺序发生。

有没有人知道创建对象的细节?如果你创建一个子类,它是如何工作的?是不是首先创建超类,然后调用它的构造函数,然后以某种方式将子类合并到现有的构造中,然后调用它的构造函数?有人会以某种方式认为构造函数“创建”了一个对象吗?

我真的很期待看到你的答案!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-27 00:57:07

血淋淋的细节在Java Language Spec中有所涉及,这里是你每天需要知道的基础知识(下一节继续,我指出了类初始化,当一个类第一次有新的调用它时会发生(也有其他方法发生))。

new为对象分配内存,并将其初始化为0、null、false (取决于类型)。这就是为什么保证所有实例变量都有初始值的原因。

假设new成功,则调用构造函数以允许程序员执行其他初始化/任务。

构造函数做的第一件事是调用父构造函数(super(...))。这在层次结构中一直向上发生,直到到达没有父级的java.lang.Object。

在执行构造函数之前,运行任何实例初始化块,后面是任何具有赋值运算符的实例变量。

如果一个实例变量被标记为final并且有一个赋值运算符,这是一个特殊的情况,如果我没记错的话,这似乎发生在调用super之前(这其中有一些技巧)。

所有这些都是为什么您不应该(隐式或显式地)引用this.method()或将其传递到构造函数之外的原因,因为您将使用一个未完成的对象。

票数 1
EN

Stack Overflow用户

发布于 2013-05-27 01:18:56

据我所知,你的解释是正确的。构造函数背后的主要思想是,您可以强制对象的有效状态。

考虑一个名为"Rational“的类,它有两个属性: numerator (int)和denominator (int),代码如下所示(为简洁起见,我省略了getter和setter)

代码语言:javascript
复制
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构造函数。

以下代码片段:

代码语言:javascript
复制
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首先被初始化

票数 1
EN

Stack Overflow用户

发布于 2013-05-27 00:54:13

从规范中消除您对new和构造函数角色的疑虑:

Creating Objects

如您所知,类提供了对象的蓝图;您可以从一个类创建一个对象。以下每条取自CreateObjectDemo程序的语句都创建一个对象并将其赋值给一个变量:

代码语言:javascript
复制
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);

第一行创建Point类的对象,第二行和第三行分别创建Rectangle类的对象。

这些语句中的每一个都有三个部分(下面将详细讨论):

声明:以粗体显示的代码集是将变量名与对象类型相关联的所有变量声明。

Instantiation:关键字是一个创建对象的Java运算符。

Initialization:新运算符之后是对构造函数的调用,该构造函数初始化新对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16761408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档