10

我知道私有实例变量是通过它们的公共 getter 和 setter 方法访问的。

但是当我在 IDE 的帮助下生成构造函数时,它会直接初始化实例变量,而不是通过它们的 setter 方法来初始化它们。

Q1。因此,我应该更改 IDE 为构造函数生成的代码,以通过它们的 setter 方法初始化这些实例变量。

Q2。如果是,那么为什么 IDE 不以这种方式生成构造函数代码?

============================= 已编辑==================== ====================

  • 我使用 Eclipse 和 Netbeans IDE

  • 这是一个普遍的问题。但是正如@Lords 所问的那样,答案是否取决于我们的构造函数是公共的还是受保护的,还是包私有的还是私有的?

4

7 回答 7

12

永远不应该从构造函数中调用非最终方法。类构造函数用于初始化一个对象,直到构造函数返回,对象才处于一致状态。如果你的构造函数调用了一个后来被子类覆盖的非最终方法,你会得到奇怪的、意想不到的结果,因为在调用被覆盖的方法时对象没有完全初始化。

考虑这个人为的例子:

class A {
    private int x;

    public A() {
        setX(2);
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getX() {
        return x;
    }
}

class B extends A {
    private int number = 10;

    @Override        
    public void setX(int x) {
        // set x to the value of number: 10
        super.setX(number);
    }
}

public class Test {
    public static void main(String[] args) {
        B b = new B();
        // b.getX() should be 10, right?
        System.out.println("B.getX() = " + b.getX());
    }
}

这个程序的输出是:

B.getX() = 0

原因是调用的时候B'snumber成员没有初始化,所以使用了它的默认值of。setX0

这篇文章有更透彻的解释,Effective Java也是如此。

于 2010-04-02T20:23:55.667 回答
2

构造函数用于初始化。直接在构造函数中初始化私有实例变量。方法定义对象的行为。行为发生在实例化/初始化之后。使用 setter 方法操作实例变量的状态。这是经典的 OOP 思维,可能也是您的 IDE 生成代码的原因。

于 2010-04-02T19:21:07.810 回答
1

那要看。如果您的 setter/getter 只是访问成员,您应该直接访问它们。如果您还有一些代码,请使用 setter。

于 2010-04-02T18:55:37.733 回答
0

您应该决定将使用构造函数初始化哪些字段以及使用 setter 初始化哪些字段。(两者都有可能)我更喜欢尽可能多地使用构造函数,并且通常没有设置器。

这应该在 IDE 中是可配置/可选择的。如果不了解您的 IDE,就无法知道它为什么会这样工作。

于 2010-04-02T18:56:24.943 回答
0

很好的答案。只想添加 Eclipse(我经常使用的那个)有模板,您可以修改这些模板以按照您想要的方式生成代码。它可以帮助根据您的需要调整代码。

PS。我宁愿使用 setter 和 getter。就像一种习惯一样,保持代码的连贯性,我觉得如果我在代码中保持这种习惯,其他人会更容易阅读。

于 2010-04-02T19:24:17.393 回答
0

首先initialization != setters(至少不总是)

但是 IDE 只是与曾经受人尊敬的 JavaBean 设计模式很好地配合,假设属性更改应该通过 setter 发生。

所以,这是一个设计问题。如果您的类代表纯值对象,则通过初始化没有害处= 但是如果您的类有可能成为JavaBean其属性更改不仅仅是初始化或赋值的类,请使用set*调用。

于 2010-04-02T19:29:54.837 回答
0

一个类的私有实例变量应该(我相信需要)在任何类构造函数之外声明。如果我可以将您的问题的一部分分为两部分:

Q1)如果实例变量在类被实例化时被初始化,与局部变量不同,为什么还要在给定的类构造函数中做额外的工作(?)。

A1) 虽然你不需要初始化实例变量(私有字符串 someString;默认为 null 并且是合法的),但这样做的一个原因是编译器分配的默认值可能不是你想要的值,或者更糟糕的是,不正确 (编译器应该捕获的)。

Q2)假设上面的部分,get的意义是什么;放; 特性?

A2)除了它们比等效方法更容易和更优雅之外,属性可以在您的类中的任何时候使用(显然),它们可以用作简单的分配或包含额外的代码(有人已经说明了这一点用于验证信息) ,最后数据是自包含在类中的,因此更容易调试。

说了这么多,你可能有一个完全正当的理由来做与书本或其他人所说的不同的事情。总是有人接受“规则”,你应该相应地编码。

于 2010-08-05T18:40:59.743 回答