setter 方法是不是必须有一个参数?
Posted
技术标签:
【中文标题】setter 方法是不是必须有一个参数?【英文标题】:Is it necessary for setter methods to have one argument?setter 方法是否必须有一个参数? 【发布时间】:2010-09-23 05:52:07 【问题描述】:setter 方法是否必须有一个参数?通常 setter 方法接受一个参数作为对象的某个属性的值。如果我想首先测试取决于另一个布尔参数的有效性怎么办,如果为真,则首先验证,否则只需设置值。
我通过 ftp 服务器从客户端获取值。有时这些文件包含垃圾值。例如,#3432838#9 之类的电话号码。所以在我设置值之前,我需要删除那些垃圾字符。我可以在 setter 方法中做到这一点吗?这是一种有效的方法吗?
提前致谢!
编辑:
这是否有效:
public void setSomething(String strValue)
if(checkValidity(strValue))
// set the value
else
// set the value to an empty string
【问题讨论】:
另见***.com/questions/2750/… 刚刚为您的 sn-p 添加了答案 【参考方案1】:在java bean框架模型中具体是必须的,但一般不是强制的。
当 setter 用于“交换”一个值时,您可以使用不带参数的 setter。
void setCheck()
例如可以将“检查”布尔属性设置为 true。
因此,即使它不是 java bean 术语意义上的“setter”,您也可以想象 setter 用于其他目的。
另外,根据 JavaBean 规范的第 7 节,setter 可以有多个参数,例如对于索引属性(索引属性支持一系列值。无论何时读取属性或写你只需指定一个索引来标识你想要的值。)
void setter(int index, PropertyType value); // indexed setter
void setter(PropertyType values[]); // array setter
在您的情况下,一种有效的方法是将runtime exception添加到我们函数的签名中。 这样,您就不会对已经调用您的 setter 的所有其他类进行任何不必要的编译时异常检查。
或者您可以将您的属性视为约束属性并添加非运行时异常。
需要受约束的属性设置器方法来支持 PropertyVetoException。 该文档向尝试更新的受约束属性的用户可能是 否决。 所以一个简单的约束属性可能看起来像:
PropertyType getFoo();
void setFoo(PropertyType value) throws PropertyVetoException;
这允许在需要时添加 VetoableChangeListener。
关于你的 sn-p,它是“有效的”,但可能不是最佳的,因为(如 this question 中所说):
验证应与验证方法中的 getter 或 setter 分开捕获。这样,如果需要在多个组件中重复使用验证,它就可用。 最好快速失败(因此我建议向 setter 添加异常)。【讨论】:
但是 void setCheck() 不再是“setter”了。它只是一个名称以“set”开头的普通方法。 是的:我只是说“setter”不一定附加到 Java Bean。可以出于其他目的而拒绝。【参考方案2】:通过 Java Bean 规范 setter 有一个参数。如果您添加另一个,无论出于何种原因,它不再被视为 setter。
Setter 完全可以“清理”它的参数,如果无效则抛出异常。
【讨论】:
【参考方案3】:为什么不呢。验证和验证输入是包含在设置器中的一个很好的变体。这里的问题是,如果你想允许在没有验证的情况下设置成员。
您可能需要使用某些框架的标准形式的设置器(用作 bean)。但如果你不受这种限制,你可以试试这个。
如果您认为其他代码应该进行验证但不应该设置错误的值,您也可以在 setter 中使用断言。
【讨论】:
【参考方案4】:在 Joshua Bloch(ISBN-13:978-0-321-35668-0)的“Effective Java 2nd Edition”一书中说,最好使用构建器模式而不是 bean 约定来创建对象。
例如(bean 模式):
NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);
与构建器模式一起使用:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
calories(100).
sodium(35).
carbohydrate(27).
build();
建造者模式的实现:
// Builder Pattern
public class NutritionFacts
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings)
this.servingSize = servingSize;
this.servings = servings;
public Builder calories(int val)
calories = val; return this;
public Builder fat(int val)
fat = val; return this;
public Builder carbohydrate(int val)
carbohydrate = val; return this;
public Builder sodium(int val)
sodium = val; return this;
public NutritionFacts build()
return new NutritionFacts(this);
private NutritionFacts(Builder builder)
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
当需要前两个参数时。
对于验证,您可以使用早期验证(在每个 <field>
方法中)或延迟验证(在 build() 方法中)。并且格式是一种python键值初始化。
【讨论】:
有build方法有什么意义?为什么不直接停在 .carbohydrate() ? build 方法返回一个 NutritionFacts 对象。其他人返回一个生成器。你可以这样写: NutritionFacts n = new NutritionFacts.Builder(12, 15).sodium(12).build();以上是关于setter 方法是不是必须有一个参数?的主要内容,如果未能解决你的问题,请参考以下文章