我在Eclipse中使用Java,并且阅读了thread
我真的很喜欢home's answer,因为我以前从没想过。子类实际上应该没有访问成员的整个想法。但是,如果有人想放手一搏,我有一个有趣的例子。
假设我有一个接口Buildable
和一个枚举CatanPiece
:
public interface Buildable
{
HashMap<Resource, Integer> getCost();
Buildable build( final PlayerHand payment );
}
public enum CatanPiece implements Buildable
{
ROAD
{
@Override
public HashMap<Resource, Integer> getCost()
{
if ( cost.isEmpty() )
{
cost.put( BRICK, 1 );
cost.put( LUMBER, 1 );
}
return cost;
}
},
SETTLEMENT
{
@Override
public HashMap<Resource, Integer> getCost()
{
if ( cost.isEmpty() )
{
cost.put( BRICK, 1 );
cost.put( LUMBER, 1 );
cost.put( SHEEP, 1 );
cost.put( WHEAT, 1 );
}
return cost;
}
},
CITY
{
@Override
public HashMap<Resource, Integer> getCost()
{
if ( cost.isEmpty() )
{
cost.put( WHEAT, 2 );
cost.put( ORE, 3 );
}
return cost;
}
};
protected final HashMap<Resource, Integer> cost;
private CatanPiece()
{
cost = getCost();
}
@Override
public abstract HashMap<Resource, Integer> getCost();
@Override
public Buildable build( final PlayerHand payment )
{
return ( payment.remove( cost ) ? null : this );
}
}
所以Checkstyle给了我有关我正在使用的受保护的HashMap的信息,但是对于那些了解此问题的人来说,您可以看到我没有有人滥用该变量的问题。并且我实际上将其设为私有并使用受保护的get方法,但是该方法在每个实例上的返回都是不同的。
可能的答案:忽略checkstyle警告,或者包括抽象的init()方法来初始化HashMap,然后简单地为枚举的所有成员简单地实现getCost()方法。
你怎么看?
最佳答案
Checkstyle对枚举的理解有时不完整。我猜想VisibilityModifier检查的作者没有想到Enums。枚举是一个极端的情况,需要支票的某些其他属性。
但是,偶然地,对于您而言,警告仍然是正确的。我认为,在任何情况下都不应在枚举中使用protected
字段。如果在Enum常量中需要实例特定的状态,请通过构造函数或通过静态初始化对其进行初始化。
请尝试以下方法。这应该为您带来一些好处:
Checkstyle警告消失了,因为Map
现在是private
。
现在,CatanPiece
枚举常量实际上是常量,因为成本映射图是不可变的。
惰性初始化没有开销。 CatanPiece
枚举常量的用户可以确保成本图正确初始化。
唯一的缺点是,每当扩展枚举时(例如,使用SHIP
),开发人员都不得忘记更新buildCostMap()
。这样的错误会很快出现。
public enum CatanPiece implements Buildable
{
ROAD, SETTLEMENT, CITY;
private static final Map<CatanPiece, Map<Resource, Integer>> allCosts =
buildCostMap();
private static Map<CatanPiece, Map<Resource, Integer>> buildCostMap()
{
Map<CatanPiece, Map<Resource, Integer>> result =
new HashMap<CatanPiece, Map<Resource, Integer>>();
Map<Resource, Integer> cost = new EnumMap<Resource, Integer>(Resource.class);
cost.put(Resource.WHEAT, 2);
cost.put(Resource.ORE, 3);
result.put(CITY, Collections.unmodifiableMap(cost));
cost = new EnumMap<Resource, Integer>(Resource.class);
cost.put(Resource.BRICK, 1);
cost.put(Resource.LUMBER, 1);
cost.put(Resource.SHEEP, 1);
cost.put(Resource.WHEAT, 1);
result.put(SETTLEMENT, Collections.unmodifiableMap(cost));
cost = new EnumMap<Resource, Integer>(Resource.class);
cost.put(Resource.BRICK, 1);
cost.put(Resource.LUMBER, 1);
result.put(ROAD, Collections.unmodifiableMap(cost));
return Collections.unmodifiableMap(result);
}
@Override
public Map<Resource, Integer> getCost() {
return allCosts.get(this);
}
@Override
public Buildable build(final PlayerHand payment) {
return payment.remove(cost) ? null : this;
}
}
关于java - Checkstyle默认情况下不允许使用 protected 变量,但是枚举又如何呢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23173680/