[英]Protected Variables aren't allowed by default in Checkstyle, but what about in an enum?
我在Eclipse中使用Java,并且阅读了一个线程
我真的很喜欢home的 答案 ,因为我以前从未真正考虑过它。 子类的整个想法实际上不应该访问成员。 但是,如果有人想尝试一下,我有一个有趣的例子。
假设我有一个Buildable
接口和一个Enum 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检查的作者没有想到枚举。 枚举是一个极端的情况,需要支票的某些其他属性。
但是,偶然地,对于您而言,警告仍然是正确的。 我认为,在任何情况下都不应在枚举中使用protected
字段。 如果在Enum常量中需要实例特定的状态,请通过构造函数或通过静态初始化对其进行初始化。
请尝试以下方法。 这应该为您带来一些好处:
Map
现在是private
。 CatanPiece
枚举常量现在是真正的常量,因为成本映射图是不可变的。 CatanPiece
枚举常量的用户可以确保成本图正确初始化。 唯一的缺点是,每当扩展Enum时(例如,使用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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.