在不使用setter的情况下更改私有字段成员

时间:2013-07-22 11:05:59

标签: java oop encapsulation

在开发我最近的项目时,我发现了一些违反封装和可见性规则的东西,因为我理解它们。

在我的GUI类中,我为我的应用程序中的文本字段和按钮创建了几个类变量,并将它们全部设置为私有。我还为按钮和文本字段设置了getters,返回私有成员的值。在我的SqlStatements课程中,我引用了getter,然后在getter上调用setText()方法,它会更改私有成员字段的值。这怎么可能?

例如:

public class InitGUI {
    public static JTextField getfNameField() {     <---- getter for JTextField
        return fName;
    }

    private static JTextField fName;   <---- JTextField variable.
}

public class SqlStatements {
    // how is this able to change the value of a private member?
    InitGUI.getmNameField().setText("");
}

6 个答案:

答案 0 :(得分:11)

您将不可变性与可见性混为一谈。通过为私有字段提供getter(打破封装),您可以将它的方法暴露给外部世界。 (可能是一些改变字段内部状态的方法 - 以及你的类的结果)。

答案 1 :(得分:2)

  

这怎么能改变私人会员的价值呢?

更改fName私有字段的值 - 它仍然是对同一JTextField的引用。您所做的只是在JTextField对象上调用方法。

答案 2 :(得分:0)

  

getter和setter的目的是提供限制/禁用   对私有变量的不必要的修改。

如果这对您没用,则无需将其定义为私有

答案 3 :(得分:0)

你的问题是你对私人工作方式的假设是不正确的,因此,你的代码暴露太多。而不是,

public class InitGUI {
    public static JTextField getfNameField() {     <---- getter for JTextField
        return fName;
    }

    private static JTextField fName;   <---- JTextField variable.
}

public class SqlStatements {
    // how is this able to change the value of a private member?
    InitGUI.getmNameField().setText("");
}

你最好这样做:

public class InitGUI {
    // for heaven's sake, get rid of the statics!    
    private JTextField fName= new JTextField(10);   

    public String getfNameText() {     
        return fName.getText();
    }

    public void setfNameText(String text) {
       fName.setText(text);
    }

}

这将限制您的组件仅暴露于您想要的曝光。

同样,请避免不必要地使用静电。

答案 4 :(得分:0)

您对成员在java中的工作方式感到困惑。私人会员确实是私人会员。当您通过getter方法访问该成员时,它确实可以被“修改”。 getter返回存储在成员中的class实例。无论您对此实例执行什么操作都会影响私有变量,因为它们都是相同的实例

但它不返回的是该成员存储的memory address。因此,您无法通过执行来替换实例;

JTextField field = InitGUI.getmNameField();
field = new JTextField(); // this can't affect the original.

这篇文章Is Java "pass-by-reference" or "pass-by-value"?可能有助于按价值性质解释java的引用。

答案 5 :(得分:0)

您可以为JTextField的特定字段提供公共getter,而不是整个对象的getter。这样您就可以避免有人设置字段。

e.g。

public String getFname(){
return fName.getXXXX();
}