在Java中设置和获取方法?
我怎样才能使用这个方法,并且为什么要使用它们? 他们真的有帮助吗? 你也可以给我一些例子,并获得方法?
Set和Get方法是数据封装的一种模式。 您不必直接访问类成员variables,而是定义get
方法来访问这些variables,并set
方法来修改它们。 通过以这种方式封装它们,你可以控制公共接口,将来你需要改变这个类的内部工作。
例如,对于一个成员variables:
Integer x;
你可能有方法:
Integer getX(){ return x; } void setX(Integer x){ this.x = x; }
chiccodoro也提到了一个重要的一点。 如果您只想允许任何外部类的读取访问字段,您可以通过只提供一个公共get
方法,并保持私有或不提供set
。
我想添加到其他答案,可以使用setter来防止将对象置于无效状态。
例如,假设我必须设置一个TaxId,build模为一个String。 setter的第一个版本可以如下所示:
private String taxId; public void setTaxId(String taxId) { this.taxId = taxId; }
但是我们最好避免使用taxId来设置对象,所以我们可以引入一个检查:
private String taxId; public void setTaxId(String taxId) throws IllegalArgumentException { if (isTaxIdValid(taxId)) { throw new IllegalArgumentException("Tax Id '" + taxId + "' is invalid"); } this.taxId = taxId; }
下一步,为了提高程序的模块化,将TaxId本身作为一个对象,能够自我检查。
private final TaxId taxId = new TaxId() public void setTaxId(String taxIdString) throws IllegalArgumentException { taxId.set(taxIdString); //will throw exception if not valid }
同样,对于吸气剂,如果我们没有价值呢? 也许我们想要有一个不同的道路,我们可以说:
public String getTaxId() throws IllegalStateException { return taxId.get(); //will throw exception if not set }
我想你想要这样的东西:
public class Person { private int age; //public method to get the age variable public int getAge(){ return this.age } //public method to set the age variable public void setAge(int age){ this.age = age; } }
你只是在一个对象实例上调用这样一个方法。 这样的方法是非常有用的,如果设置一些东西应该有副作用。 例如,如果您想对以下某些事件做出反应:
public void setAge(int age){ this.age = age; double averageCigarettesPerYear = this.smokedCigarettes * 1.0 / age; if(averageCigarettesPerYear >= 7300.0) { this.eventBus.fire(new PersonSmokesTooMuchEvent(this)); } }
当然,如果有人忘记调用setAge(int)
,他应该直接使用this.age
设置age
这可能是危险的。
使用accessor方法优于直接访问字段,因为它控制字段的访问方式(可能会强制数据检查等)并与接口(接口不能要求字段存在,只有方法)配合。
Setters和getters用来replace直接从外部类访问成员variables。 如果您在访问属性时使用setter和getter,则可以包括初始化,错误检查,复杂转换等。一些示例:
private String x; public void setX(String newX) { if (newX == null) { x = ""; } else { x = newX; } } public String getX() { if (x == null) { return ""; } else { return x; } }
使用getters和setter(称为encapsulation
或data-hiding
)的一些好处:
(原来在这里回答)
1.一个类的字段可以是只读的(只提供getter)或者只写(只提供setter)。 这使得class级可以完全控制谁来访问/修改其字段。
例:
class EncapsulationExample { private int readOnly = -1; // this value can only be read, not altered private int writeOnly = 0; // this value can only be changed, not viewed public int getReadOnly() { return readOnly; } public int setWriteOnly(int w) { writeOnly = w; } }
2.一个类的用户不需要知道类是如何实际存储数据的。 这意味着数据被分离并且独立于用户而存在,从而允许代码被更容易地修改和维护。 这使得维护人员能够频繁更改错误修复,devise和性能增强,而不会影响用户。
而且,被封装的资源可以被每个用户统一访问,并且具有与用户无关的相同的行为,因为这个行为是在类中内部定义的。
示例(获取值):
class EncapsulationExample { private int value; public int getValue() { return value; // return the value } }
现在,如果我想要返回两倍的价值呢? 我可以改变我的getter,所有使用我的例子的代码都不需要改变,并且会得到两倍的值:
class EncapsulationExample { private int value; public int getValue() { return value*2; // return twice the value } }
3.使代码更清晰,更易读,更容易理解。
这里是一个例子:
没有封装:
class Box { int widthS; // width of the side int widthT; // width of the top // other stuff } // ... Box b = new Box(); int w1 = b.widthS; // Hm... what is widthS again? int w2 = b.widthT; // Don't mistake the names. I should make sure I use the proper variable here!
封装:
class Box { private int widthS; // width of the side private int widthT; // width of the top public int getSideWidth() { return widthS; } public int getTopWIdth() { return widthT; } // other stuff } // ... Box b = new Box(); int w1 = b.getSideWidth(); // Ok, this one gives me the width of the side int w2 = b.getTopWidth(); // and this one gives me the width of the top. No confusion, whew!
看看你有更多的控制你在哪些信息,以及在第二个例子中有多清楚。 请注意,这个例子是微不足道的,在现实生活中,你将要处理大量资源的类,这些资源被许多不同的组件访问。 因此,封装资源使得我们更清楚哪些是我们正在访问和以什么方式(获取或设置)。
这个主题good SO thread
。
这里是关于数据封装的good read
。
上面的回答比我更好地总结了getter和setter的作用,但是我想补充一点,你的代码应该被理想化地构造来减less纯getter和setter的使用,也就是那些没有复杂构造,validation等的应用,因为他们打破封装。 这并不意味着你永远不能使用它(stivlo的答案显示了一个很好的使用getter和setter的例子),只是尽量减less你使用它们的频率。
问题是getter和setter可以作为一个解决办法来直接访问私有数据。 私人数据被称为私人数据,因为它不打算与其他对象共享; 它的意思是表示对象的状态。 允许其他对象访问一个对象的私有域失败了首先将其设置为私有的全部目的。 而且,你为每一个你所写的吸气器或者吸气器都引入了耦合。 考虑这个,例如:
private String foo; public void setFoo(String bar) { this.foo = bar; }
如果在某个地方,你决定不再需要富人,或者你想把它变成一个整数,会发生什么? 现在每个使用setFoo方法的对象都需要和foo一起改变。
只是因为OOP规则:数据隐藏和封装。 在大多数情况下将对象声明为公共并在运行中更改它是非常糟糕的做法。 另外还有很多其他的原因,但是根源是OOP中的封装。 和“买书或阅读面向对象的程序devise”,在阅读任何有关面向对象的书籍之后,你都会明白这一点。
get()set()方法的好处如下。
- 你可以轻松地序列化你的对象。
- 您可以从包含的类中创build一个持久对象。
- 您可以轻松地将属性转换为JSON。
- 在DAO层(像Hibernate这样的框架)中,你可以直接把对象保存到数据库。
- 容易理解面向对象的概念。
- 除了可能在单音模式中需要所有devise模式。
- 保护直接访问的财产安全。
- 多态性,封装可以很容易地被这种types的类来理解和实现。
例:
private String personName; private int personId; public void setPersonName(String name) throws Exception{ if(!(name.equals("")||name=="")){ this.personName = name; } } public String getPersonName(){ return this.personName; } public void setPersonId(int id) throws Exception{ this.personId = id; } public int getPersonId(){ return this.personId; }
上面的答案都假设所讨论的对象是一个具有行为的对象。 OOP中的高级策略是将数据对象(即zip,只有字段)和行为对象分开。
使用数据对象,省略getter并且使用公有字段是完全正确的。 他们通常没有setter,因为他们通常是不可变的 – 他们的字段是通过构造函数设置的,而不是再次。 看看鲍勃马丁的清洁代码或Pryce和Freeman的增长面向对象软件…的细节。
public class Person{ private int age; public int getAge(){ return age; } public void setAge(int age){ this.age = age; } }
我想这是你想..这也叫pojo
这是set方法的代码
public void setAge(int age){ this.age = age; }
它看起来像你想要做类似于C#的东西,如果你想setAge创build方法
setAge(int age){ this.age = age;}
我没有看到第二个问题(为什么)的简单答案。 所以在这里。
假设您的代码中经常使用公用字段。 无论何时您决定在给予或设置此字段之前需要做些额外的事情,您都有问题。 你必须为这个字段创build一个特殊的getter和setter,并把你的完整代码从使用这个字段直接改为使用getter和setter。
现在想象你正在开发一个被很多人广泛使用的图书馆。 当你需要像上面那样进行更改,并将该字段的直接访问权限设置为私人时,使用该字段的所有人员的代码将会中断。
使用getter和setter是关于代码的未来规划,它使得它更加灵活。 当然,您可以使用公共字段,特别是对于只保存一些数据的简单类。 但是,私下编写这个字段并为其编写一个get和set方法是一个好主意。
这个答案是从另一个问题合并。
您的getAge()
方法在Java中称为实例方法。
要调用一个实例方法,你应该有一个定义这个方法的类的对象。
例如,如果这个方法在一个叫做Person
的类中,那么
-
使用new运算符创build一个Person对象
Person p = new Person();
-
要获取
Person
对象的年龄,请使用此方法p.getAge()