我已经注意到Java中的许多地方(包括C#),许多“getter”方法都以“get”为前缀,而其他许多方法则没有。 我从未注意到Sun似乎遵循的任何模式。 在getter方法名称中使用“get”有哪些指导或规则?
它归结为语义。 是的,C#有“属性”,它为你提供了一个get / set'方法'存根......但.NET Framework中以“Get”开头的函数(...“methods”...)应该提示开发人员认为某些操作正在发生,其唯一目的是获得一些结果。
你可能认为这很奇怪,并说“为什么不只是使用返回类型来引导人们进入?”,答案很简单。 考虑以下方法:
public Person CreatePerson(string firstName, string lastName) {...}
只是通过该方法的名称,您可能会认为将涉及数据库活动,然后将返回新创建的“人员”。
但是,这个怎么样:
public Person GetPerson(string firstName, string lastName) {...}
只需使用该方法的名称,您就可以假设正在对数据库中的人进行100%“安全”检索。
你永远不会多次打电话给“CreatePerson”......但是你应该总是安全地打电话给“GetPerson”。 (它不应该影响应用程序的“状态”)。
Java中的“get”和“set”前缀对最初用作表示java bean的约定。 后来,它变成了一个封装约定,因为Java与C#不同,没有适当的属性。
Java中的最佳实践是使用属性的get和set前缀。
框架,标记库等将查找具有这些前缀的方法并将其用作属性。
所以,如果你有一个像这样的java类......
public class User{
private String name;
public String getName(){ return name;}
public void setName(String name){ this.name = name; }
}
..使用struts-tags(或任何其他基于ognl的标记库),您将使用user.name
访问name属性。
Spring框架也在xml配置文件中使用此约定。
我个人喜欢以下规则:
set
方法直接修改,就可以使用get
前缀 get
前缀(即没有等效的setXXX方法) 第二种情况的基本原理是,如果该值实际上不是用户可设置的“属性”,则它不应该需要get / set方法对。 这意味着如果遵循此约定并且您看到getXXX方法,则可以假设存在setXXX方法。
例子:
String.length()
- 因为字符串是不可变的,所以length是只读值 ArrayList.size()
- 添加或删除元素时大小会更改,但您无法直接设置它 Java(尚未)支持属性。 吸气剂和二传手是一个可以解决这个问题的小屋。 其他语言 - 包括C# - 支持属性,您应该使用它们。 这不仅仅是一种“最佳实践”的事情:C#中的序列化将依赖于属性,而不是依赖于getter和setter,因此如果您需要序列化类,不使用属性可能会在将来导致各种问题。
属性的优点是它们使代码更具可读性。 就像是
obj.setX(10);
在Java中,成为
obj.X = 10;
在幕后,X是一种方法,而不是变量,因此可以执行脏输入检查等。
它当然是API经常暴露只读属性而没有get
前缀的情况: String.length()
甚至更新的Buffer.capacity()
都是合理的例子。
这样做的好处是减少了绒毛。 缺点是任何试图根据约定自动确定属性的东西都不会发现它们。 就个人而言,我倾向于在包含前缀方面犯错误。
当然,在C#中,它几乎无关紧要,因为无论如何都有“真正的”属性:)
这取决于。 即使在没有属性的语言中,它通常也是冗余信息。
在C ++中,代替getAttr()/ setAttr()对,通常提供两个Attr()函数的重载:void Attr(Foo f); // setter Foo Attr(); //吸气剂
在Java中,通常的做法是为get / set添加前缀。 我不得不说最好的做法是遵循你的语言标准。 在Java中,人们期望看到获取/设置前缀,因此省略它们可能会使人感到困惑,即使它们并非严格必要。
Objective C 2.0也使用相同的点语法来使用属性。
在此之前,它对getter和setter使用了略微不同的命名方案(当然,它仍然可以与属性一起使用,或者用于普通的旧属性)。
value = [obj attr];
[obj setAttr:value];
[obj getAttr:&value];
也就是说,get以不同的方式使用。 它不返回值,而是将结果存储在传入的变量中。
典型的getter与属性的名称相同,setter是以set为前缀的属性(根据Java的约定)。 这些约定由KVO(键值观察)系统使用,因此应该遵守。
只是一个简短的附录:另一个约定是布尔字段的getter以“is”而不是“get”作为前缀,例如bool isEnabled() { return enabled; }
bool isEnabled() { return enabled; }