【发布时间】:2012-06-25 05:04:05
【问题描述】:
我有一些这样的 Java 枚举
public enum Aggregation
{
MORTGAGE( "Mortgage" ),
POOLS( "Pools" ),
PORTFOLIO( "Portfolio" );
private Aggregation( final String name )
{
m_Name = name;
}
private String m_Name;
static Map< String, Aggregation > c_LOOKUP =
new HashMap< String, Aggregation >();
static {
for (Aggregation agg:values()){
c_LOOKUP.put(agg.m_Name,agg);
}
}
public Aggregation lookup(String name){
return c_LOOKUP.get( name );
}
@Override
public String toString()
{
return m_Name;
}
}
public enum Interval
{
MONTHLY( "Monthly" ),
QUARTLY( "Quartly" ),
SEMIANNUALLY( "SemiAnnually" ),
ANNUALLY("Annually");
private Interval( final String name )
{
m_Name = name;
}
private String m_Name;
static Map< String, Interval > c_LOOKUP =
new HashMap< String, Interval >();
static {
for (Interval agg:values()){
c_LOOKUP.put(agg.m_Name,agg);
}
}
public Interval lookup(String name){
return c_LOOKUP.get( name );
}
@Override
public String toString()
{
return m_Name;
}
}
如您所见,这里有很多代码重复。如果有一种方法可以引入抽象的共同祖先类之类的东西,那就太好了。但是java枚举不能与生俱来。最好的方法是什么?谢谢。
编辑: 我制定了一个类似于 ŁukaszBachman 和 missingfacktor 的版本
static public enum Aggregation
{
MORTGAGE( "Mortgage" ),
POOLS( "Pools" ),
PORTFOLIO( "Portfolio" );
private final String m_Name;
final static private ReverseDictionary< Aggregation > c_DICTIONARY =
new ReverseDictionary< Aggregation >( Aggregation.class );
static public Aggregation lookup( final String name )
{
return c_DICTIONARY.lookup( name );
}
private Aggregation( final String name )
{
m_Name = name;
}
@Override
public String toString()
{
return m_Name;
}
}
static public enum Interval
{
MONTHLY( "Monthly" ),
QUARTLY( "Quartly" ),
SEMIANNUALLY( "SemiAnnually" ),
ANNUALLY( "Annually" );
private final String m_Name;
final static private ReverseDictionary< Interval > c_DICTIONARY =
new ReverseDictionary< Interval >( Interval.class );
static public Interval lookup( final String name )
{
return c_DICTIONARY.lookup( name );
}
private Interval( final String name )
{
m_Name = name;
}
@Override
public String toString()
{
return m_Name;
}
}
static public class ReverseDictionary< E extends Enum< E >>
{
Map< String, E > c_LOOKUP = new HashMap< String, E >();
public ReverseDictionary( final Class< E > enumClass )
{
for( final E agg : EnumSet.allOf( enumClass ) )
{
c_LOOKUP.put( agg.toString(), agg );
}
}
public E lookup( final String name )
{
return c_LOOKUP.get( name );
}
}
我看到了一些道理。但是,它仍然不是很令人满意。
-
lookup(String)的接口很难定义,因为返回类型不同 - 我可以理解
lookup(String)并不是真正的重复,而是一种规范,但我仍然觉得 m_Name 字段和 toString() 逻辑有点多余。我们确实指定了一类枚举,在我看来,这似乎是 "is-a" 关系。
【问题讨论】:
-
如果继承不起作用,委托会解决问题。
-
你不能继承静态的东西,所以即使枚举支持实现继承,也无济于事。
-
buc,你能说得更具体一点吗?谢谢。
-
您是否考虑过使用valueOf 代替所有查找内容?它似乎是大部分重复的代码,无论如何你都可以在任何枚举中免费获得它。
-
所以你有所有这些逻辑只是让值名称全部大写,而它们的内容只有一个大写字母?我可能会更改值的命名以匹配它们所需的内容,从而消除所有这些逻辑。我知道你在问一个一般性的问题,所以这只是一个评论。这只是正式实践(此处的命名约定)引入其他不必要的逻辑的情况之一。放弃形式可以产生更好的代码,而不必使用一些花哨的模式。
标签: java oop inheritance enums