setter方法有必要有一个参数吗?

时间:2008-11-20 13:07:41

标签: java setter

setter方法是否需要有一个参数?通常,setter方法接受一个参数作为Object的某个属性的值。如果我想首先测试依赖于另一个布尔值的参数的有效性,如果为真,则首先验证,否则只需设置值。

我通过ftp服务器从客户端获取值。有时这些文件包含垃圾值。例如,#3432838#9等电话号码。所以在我设置值之前,我需要删除那些垃圾字符。我可以在setter方法中做到吗?这是一种有效的方法吗?

提前感谢一大堆!

修改

这是否有效:

public void setSomething(String strValue){ 
     if(checkValidity(strValue)){ 
         // set the value 
     } else { 
         // set the value to an empty string
     }  
  }

4 个答案:

答案 0 :(得分:12)

特别是在java bean框架模型中,它通常不是必需的。

当你想要“交换”一个值时,你可以让setter没有参数。

void setCheck()
例如,

可以将“check”布尔属性设置为true。

因此即使它不是java bean意义上的“setter”,你也可以想象用于其他目的的setter。

另外,根据JavaBean规范的第7节,setter可以有多个参数,例如对于Indexed属性(索引属性支持一系列值。每当读取属性或写完你只需指定一个索引来识别你想要的值。)

void setter(int index, PropertyType value); // indexed setter
void setter(PropertyType values[]); // array setter

在您的情况下,有效的方法是在我们的功能签名中添加runtime exception
这样你就不会对已经调用你的setter的所有其他类进行任何不必要的编译时异常检查。

或者您可以将您的属性视为约束属性并添加非运行时异常。

需要Constrained属性setter方法来支持PropertyVetoException。 此文档向尝试更新的受约束属性的用户提供 否决。 因此,简单的约束属性可能如下所示:

PropertyType getFoo();
void setFoo(PropertyType value) throws PropertyVetoException;

允许在需要时添加VetoableChangeListener。


关于你的代码段,它是“有效的”但可能不是最佳的,因为(如this question中所述):

  • 验证方法中的验证应与getter或setter 分开捕获。这样,如果需要在多个组件之间重用验证,则可以使用它。
  • 最好快速失败(因此我的主张是向设置者添加例外)。

答案 1 :(得分:5)

通过Java Bean规范setter有一个参数。如果你添加另一个,无论出于何种原因,它不再被视为setter。

Setter完全有效“清理”其参数,或者如果无效则抛出异常。

答案 2 :(得分:2)

为什么不呢。验证和验证输入是包含在setter中的一个很好的变体。这里的问题是,如果你想允许设置成员而不进行验证。

对于您使用的某个框架(用作bean),您可能需要setter的标准形式。但如果你不受这种限制,你可以试试这个。

如果你认为其他代码应该进行验证但是错误值永远不应该设置,你也可以在setter中使用asserts。

答案 3 :(得分:1)

Joshua Bloch撰写的“Effective Java 2nd Edition”一书(ISBN-13:978-0-321-35668-0)表示,最好使用构建器模式而不是对象创建的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键值初始化。