繁体   English   中英

Checkstyle默认情况下不允许使用受保护的变量,但是枚举又如何呢?

[英]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常量中需要实例特定的状态,请通过构造函数或通过静态初始化对其进行初始化。

请尝试以下方法。 这应该为您带来一些好处:

  • Checkstyle警告消失了,因为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM