首页 文章

Java - 应该通过getter和setter方法在构造函数中访问私有实例变量吗?

提问于
浏览
10

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

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

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

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

============================= EDITED ==================== ===================

  • 我使用Eclipse和Netbeans IDE

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

7 回答

  • 0

    您应该 never 从构造函数中调用非final方法 . 类构造函数用于初始化对象,并且在构造函数返回之前,对象不处于一致状态 . 如果构造函数调用后来被子类覆盖的非final方法,则可能会得到奇怪的,意外的结果,因为在调用重写方法时对象未完全初始化 .

    考虑这个人为的例子:

    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
    

    原因是 Bnumber 成员在调用 setX 时未初始化,因此使用其默认值 0 .

    This article和Effective Java有更全面的解释 .

  • 2

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

  • 0

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

  • 0

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

    这应该在IDE中可配置/可选 . 在不了解您的IDE的情况下,无法知道它为何如此工作 .

  • 1

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

    PS . 我更喜欢使用setter和getter . 作为一种习惯,保持代码连贯,如果我把习惯放在代码上,我觉得对别人来说会更容易阅读 .

  • 0

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

    但IDE只是在曾经受到尊重的JavaBean设计模式中表现良好 . 假设属性更改应该通过setter进行 .

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

  • 12

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

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

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

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

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

    所有这一切,你可能有一个完全正确的理由做事情不同于一本书或某人别的说 . 总是接受“规则”,你应该相应地编码 .

相关问题