使用构造函数体定义的本地类是否有问题

时间:2015-08-10 13:43:03

标签: java enums local-class

我有以下枚举:

enum FilterFactory {

    INSTANCE;

    private final Map<FilterType, Creator> creators;

    private FilterFactory() {
        creators = new HashMap<>();

        class SimplCreator implements FilterCreator{
            @Override
            public FilterDTO createDto() {
                return new FilterDTO();
            }
        } //Local class within the constructor

        creators.put(FilterType.DATE, new FilterCreator(){
            @Override
            public FilterDTO createDto() {
                return new DynamicDTO();
            }
        });

        creators.put(FilterType.DROP_DOWN_LIST, new SimplCreator());
        creators.put(FilterType.FIELD, new SimplCreator());
    }

    private static interface Creator{
        public FilterDTO createDto();
    }
    //Other staff
}

事情是我从未在构造函数体中使用本地类。它会导致一些错误,这样做是不是很糟糕?另外,构造函数enu的构造函数。

2 个答案:

答案 0 :(得分:1)

我看到的唯一问题是,您正在为FilterFactory的每个实例(需要更多内存)创建FilterCreator的新实例。您可以通过创建一些常量来防止这种情况:

enum FilterFactory {

    INSTANCE;

    private final Map<FilterType, Creator> creators = new HashMap<>();

    private static final SimplCreator DEFAULT_CREATOR = new Creator() {
        @Override
        public FilterDTO createDto() {
            return new FilterDTO();
        }
     }

    private static final FilterCreator DYNAMIC_CREATOR = new Creator(){
        @Override
        public FilterDTO createDto() {
            return new DynamicDTO();
        }
    }

    private FilterFactory() {
        creators.put(FilterType.DATE, DYNAMIC_CREATOR);
        creators.put(FilterType.DROP_DOWN_LIST, DEFAULT_CREATOR);
        creators.put(FilterType.FIELD, DEFAULT_CREATOR);
    }

    private static interface Creator{
        FilterDTO createDto();
    }
    //Other stuff
}

答案 1 :(得分:1)

你的方法很好,但是在Java 8中你可以使用方法引用或lambdas(并用更标准的Supplier<FilterDTO>替换你的Creator)来使它更好一点:

import java.util.function.Supplier;

enum FilterFactory {

    INSTANCE;

    private final Map<FilterType, Supplier<FilterDTO>> creators;

    private FilterFactory() {
        creators = new EnumMap<>(FilterType.class); // a bit more efficient :)
        creators.put(FilterType.DATE, DynamicDTO::new);
        creators.put(FilterType.DROP_DOWN_LIST, SimpleDTO::new);
        creators.put(FilterType.FIELD, SimpleDTO::new);
    }

    // other stuff ... 
}

这里我使用构造函数的method reference来实例化Supplier<FilterDTO>。我也可以使用一个lambda表达式,说“什么都不给,给我一个FilterDTO”:

creators.put(FilterType.DATE, () -> new DynamicDTO());
...

这两个变体(方法参考vs lamdbas)基本相同,你应该使用更清楚的东西(引用:Java's language architect himself)。我个人认为方法参考在视觉上更清晰,虽然它确实需要一些习惯。