为类型安全扩展字符串 - Java

时间:2011-12-14 18:37:43

标签: java hibernate oop type-safety

我正在考虑使用Java中的设计,我想要一个字符串对象但是具有更多'类型安全'而不仅仅是类String。这是因为我有许多用于Hibernate的'POJO'对象,代表我的数据库表。这些类中的每一个都有大量的公共静态字段,表示类的属性,即:

public class PersistantBean {
    public static String PROP_FIELD_COLUMN_ONE="columnOne";
    public static String PROP_FIELD_COLUMN_TWO="columnTwo";
    // [...]

当我们需要以通用方式访问属性时,可以使用这些属性,例如代码我目前正在撰写.parseAndSet(PROP_FIELD_PRICE,"£3.00")

我希望能够在PROP_FIELD_...字段中添加更强的类型,以便我可以写

public class PersistantBean {
    public static PropertyName PROP_FIELD_COLUMN_ONE="columnOne";
    public static PropertyName PROP_FIELD_COLUMN_TWO="columnTwo";
    // [...]

对项目的其他部分进行最小的更改,

以便parseAndSet看起来像:

public void parseAndSet(PropertyName prop, String priceToParse)

基本上,我希望PropertyName是一个类似于String的类型,除了编译器会错误,如果我试图将String放在预期的PropertyName时,是这样的任何设计模式都可能。 (我正在回避Enums,虽然现在我提到它,Enums可能是要走的路。)

5 个答案:

答案 0 :(得分:3)

对于Java 1.5及更高版本,只需使用enum type

对于Java 1.4及更低版本,请使用typesafe enum pattern。 E.g。

public class Suit {
    private final String name;

    public static final Suit CLUBS =new Suit("clubs");
    public static final Suit DIAMONDS =new Suit("diamonds");
    public static final Suit HEARTS =new Suit("hearts");
    public static final Suit SPADES =new Suit("spades");    

    private Suit(String name){
        this.name =name;
    }
    public String toString(){
        return name;
    }

}

答案 1 :(得分:2)

我会使用Enum。这样你就可以进行编译时检查。

如果您的字符串确实具有良好的相当标准的命名约定,例如“column”+“One”,“Two”等,如您的示例中所示,您可以通过组合前缀的枚举来节省大量工作后缀为int。因此,创建一个类或实用程序方法,该方法采用前缀的枚举,例如COLUMN,并将它与int(例如2)组合在一起,以产生“columnTwo”。

替代方法可能是您的代码(如parseAndSet)验证传入的String对阵数组或合法字符串集合,或者可能是正则表达式,并抛出IllegalArgumentException。你会得到运行时检查,如果你有好的单元测试,这可能会有效。

编辑添加

@ sethupathi.t在他的回答中有一个好主意 - 在某些情况下,最好使第二个参数(我使用int)也是一个枚举。

答案 2 :(得分:2)

枚举(枚举)是一个更好的主意,如上所述。

例如:

枚举PROP_FIELD_COLUMN {    columnOne,columnTwo等 }

答案 3 :(得分:1)

据我所知,有两种合理的方法可以做你想做的事。

第一种方式(可能是最好的方式,如果它适用于你)是使用枚举,如另一个答案所述。

第二种方法,如果你在运行时不知道所有的PropertyName,可能是必要的,就是使用PropertyNameFactory:

public class PropertyNameFactory
{

  public static PropertyName getPropertyName(String propertyName)
  {
    // Check validity of the propertyName against what ever rules we
    // have defined (maybe valid propertyNames are read from a DB at
    // startup, etc).
    if (isValid(propertyName))
    {
      // Ideally get from a cache, but for the sake of the example
      // we will create a new one...
      return new PropertyName(propertyName);
    }

    throw new IllegalArgumentException("Invalid property name: " + propertyName);
  }

}

这并不理想,因为它不能为您的属性名称提供真正的类型安全性,但它确实确保了它们的有效性。

答案 4 :(得分:1)

我必须回答Enum的答案。

但是,对于您的问题,一个更直接的答案是Java为类似String的对象java.lang.CharSequence提供了一个接口,标准Java库的许多部分已经更新,以便在适当的时候接受CharSequence。但是,这不会为您提供所需的行为,即使您的类表现为String的子类型。