【问题标题】:Getter-Setter and private variables [duplicate]Getter-Setter 和私有变量
【发布时间】:2014-03-27 07:42:06
【问题描述】:

如果我可以通过 getter-returned 引用来改变私有变量的值,那不是绕过了 setter 方法吗?它不是破坏了getter-setter和私有变量的目的

public class Test{

private Dimension cannotBeChanged;

public Test(int height, int width)
{
    if(height!=3)
       cannotBeChanged.height = height;
    if(width!=3)
       cannotBeChanged.width  = width;
}

public Dimension getDimension()
{
    return cannotBeChanged;
}


public void setDimension(int height, int width)
{
    if(height!=3)
       cannotBeChanged.height = height;
    if(width!=3)
       cannotBeChanged.width  = width;    
} 

 public static void main(String [] args)
{
    Test testOne = new Test(5,5);
    Dimension testSecond = testOne.getDimension();
    testSecond.height = 3; //Changed height and width to unwanted values
    testSecond.width= 3;
}

【问题讨论】:

  • 好吧..如果不希望别人更改实际数据,您必须使用防御性副本... return new Dimension(cannotBeChanged); (复制构造函数....)
  • 我希望我的问题能因为这样一个愚蠢/简单的问题而获得如此多的支持。

标签: java private getter-setter


【解决方案1】:

是的,确实如此。我在 Clean Code 一书中的 getter 和 setter 中有以下结论;如果你真的接受它,你可以使用它。

  1. 非常邪恶:公共领域。
  2. 有点邪恶:在不需要的地方获取和设置。
  3. 好:仅在真正需要的地方使用 getter 和 setter - 制作 该类型暴露了恰好使用其状态的“更大”行为, 而不仅仅是将类型视为状态的存储库 被其他类型操纵。

【讨论】:

  • 我讨厌“邪恶”这个词。编程中没有什么是邪恶的(除了可能在 C 中飞出你鼻子的鼻恶魔;))。但是,如果默认使用,有些事情可能会导致问题。
【解决方案2】:

程序员应该为外部实体设计访问其程序的安全变量的方法。

  1. 永远不要为对象的安全属性创建任何设置器。只能提供一个 getter。
  2. 仅为那些可以在程序过程中更改的属性创建设置器。
  3. 如果您想对某些属性应用某些限制,请使用 setter,例如应用无效值检查、预填充、逻辑分析、填充另一个依赖属性、防御性复制等
  4. Getter/setter 有助于维护系统的软件熵。阅读软件entropy
  5. 不要在不需要的地方创建 getter/setter,因为它会导致 Boilerplate 代码。
  6. Getter/setter 有助于改变未来程序扩展的底层实现,例如升级日志库等

【讨论】:

    【解决方案3】:

    实际上,正确的方法是只为维度的所需部分提供设置器。像这样:

    public int getDimensionX()
    {
        return cannotBeChanged.getX();
    }
    
    public int getDimensionY()
    {
        return cannotBeChanged.getY();
    }
    

    【讨论】:

      【解决方案4】:

      这是我的一个简单的测试用例。 如您所见,您确实可以更改 Dimension 的高度,因为它是一个参考,但您不能设置新的 Dimension。

      import java.awt.Dimension;
      
      
      public class TestProperty
      {
          private String testy;
          private Dimension testDim = new Dimension(2,2);
      
          TestProperty(String testy)
          {
              this.testy = testy;
          }
      
          public String getTesty()
          {
              return testy;
          }
      
          public void setTesty(String testy)
          {
              this.testy = testy;
          }
      
          public Dimension getTestDim()
          {
              return testDim;
          }
      
          public void setTestDim(Dimension testDim)
          {
              this.testDim = testDim;
          }
      }
      

      我的 main() 方法:

      import java.awt.Dimension;
      
      public class Test
      {
      
          public static void main(String[] ARGS)
          {
              TestProperty testy = new TestProperty("Testy");
      
              String myString = testy.getTesty();
              Dimension myDimension = testy.getTestDim();
              myDimension.height = 5; //Changes the height of the private Dimension
              myDimension = new Dimension(5,3); //Does not set a new Instance of Dimension to my TestProperty.
      
              myString = "Test";
              System.out.println(myString+"|"+testy.getTesty());
              System.out.println(myDimension.height+"|"+testy.getTestDim().height);
          }
      }
      

      输出:

      Test|Testy
      3|5
      

      【讨论】:

        【解决方案5】:

        私有变量只能从它声明的类中访问。当您创建返回私有变量值的 getter 方法时,您不会获取地址,而是创建一个临时副本来保存返回值的值。 setter 方法为私有变量设置一个值,当它来自另一个类时,这是无法完成的。

        因此,getter-setter 方法基本上适用于您尝试从另一个类访问或修改私有变量时。

        注意:您正在修改的宽度和高度值是来自 Dimension 类的变量,因此它们是公共的而不是私有的。

        看看这个例子:

        public class Test {
        
        private double width, height;
        
        public Test(int height, int width)
        {
            setDimension(height, width);
        }
        
        public double getWidth() { return width; }
        public double getHeight() { return height; }
        
        
        public void setDimension(int height, int width)
        {
            if(height!=3)
               this.height = height;
            if(width!=3)
               this.width  = width;
        }
        
        public static void main(String [] args)
        {
            Test test = new Test(5,5);
            double testW = test.getWidth();
        
            testW = 3;
        
            System.out.println(testW);
            System.out.println(test.getWidth());
        }
        }
        

        返回:

        3.0
        5.0
        

        【讨论】:

          猜你喜欢
          • 2013-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-08
          相关资源
          最近更新 更多