为什么Java中的实例变量总是私有的?

Dee*_*pak 20 java instance-variables

我是Java的新手,我正在学习封装,并看到了一个示例,其中实例变量在类中声明为私有.

http://www.tutorialspoint.com/java/java_encapsulation.htm

我有2个查询:

  1. 为什么实例变量是私有的?为什么不公开?
  2. 如果实例变量公开并直接访问会怎样?我们看到任何限制吗?

你可以用一个例子来解释,如果在Java中的类中将实例变量声明为public,会出现什么问题?

Tho*_*mas 36

实例变量是私有的,以强制这些类的用户使用方法来访问它们.在大多数情况下,有普通的getter和setter,但也可以使用其他方法.

例如,使用方法可以限制对只读的访问,即如果没有setter,则可以读取字段但不写入字段.如果该领域是公开的,这是不可能的.

此外,您可以为字段访问添加一些检查或转换,这对于公共字段的普通访问是不可能的.如果某个字段是公开的,并且您以后想要通过执行其他检查等的某种方法强制所有访问.您必须更改该字段的所有用法.如果您将其设为私有,则只需稍后更改访问方法即可.

如果phone是私人的:

考虑这种情况:

class Address {
  private String phone;

  public void setPhone(String phone) {
    this.phone = phone;
  }
}

//access:
Address a = new Address();
a.setPhone("001-555-12345");
Run Code Online (Sandbox Code Playgroud)

如果我们从这个类开始,之后需要对phoneNumber执行检查(例如,一些最小长度,仅数字等),您只需要更改setter:

class Address {
  private String phone;

  public void setPhone(String phone) {
    if( !isValid( phone) ) { //the checks are performed in the isValid(...) method
     throw new IllegalArgumentException("please set a valid phone number");
    }

    this.phone = phone;
  }
}

//access:
Address a = new Address();
a.setPhone("001-555-12345"); //access is the same
Run Code Online (Sandbox Code Playgroud)

如果phone是公开的:

有人可能会这样设置phone,你无法做任何事情:

Address a = new Address();
a.phone="001-555-12345";
Run Code Online (Sandbox Code Playgroud)

如果您现在想要强制执行验证检查,则必须将其设为私有,并且无论是谁编写上述行都必须将第二行更改为:

a.setPhone("001-555-12345");
Run Code Online (Sandbox Code Playgroud)

因此,您不能在不破坏其他代码的情况下添加检查(它将不再编译).

此外,如果通过方法访问类的所有字段/属性,则保持访问一致,用户不必担心属性是存储(即是实例字段)还是计算(只有方法而没有实例字段) ).


Jon*_*eet 10

他们不具备成为私人-但他们应该.字段是实现细节 - 因此您应该将其保密.如果您想允许用户获取或设置其值,您可以使用属性来执行此操作(获取和设置方法) - 这使您可以安全地执行此操作(例如验证输入)并且还允许您更改实现详细信息(例如,委托其他对象的一些值等),而不会失去向后兼容性.

  • @Deepak:这不是代码失败的问题 - 这是一个糟糕的设计问题. (3认同)
  • @Deepak:那意味着你失去了很多控制权 - 你不能在将来改变它的名字或者如何使用它,或者线程安全等,因为世界其他地方可以随时阅读它.你不能在没有*也允许其他人改变它而没有验证等的情况下在内部使它变得可变.对于最终变量,它不是*那么糟糕,但它仍然不是一个好主意IMO. (2认同)

Boz*_*zho 7

首先,并非所有实例变量都是私有的.其中一些是受保护的,仍然保留封装.

封装的一般思想是类不应该暴露其内部状态.它应该只用它来执行它的方法.原因是每个班级都有一个所谓的"国家空间".也就是说,其字段的一组可能值.它可以控制其状态空间,但如果它暴露它,其他人可能会将其置于无效状态.

例如,如果您有两个布尔字段,并且该类只能在3种情况下正常运行:[false,false],[false,true]和[true,false].如果将字段设置为public,则另一个对象可以设置[true,true],不知道内部约束,并且调用原始对象的下一个方法将触发意外结果.