Enum将工厂称为Java内部Enum

for*_*916 6 java enums factory

我试图将Enum样式的工厂模式实现为内部枚举,但它不起作用.有没有将内部枚举分离成新文件的解决方案?换句话说,内部Enum风格的工厂模式是否可能?

代码如下.

public class SampleParent {

    private class InnerChild { }
    private class InnerChildA extends InnerChild { }
    private class InnerChildB extends InnerChild { }
    private class InnerChildC extends InnerChild { }

    enum InnerChildEnum {
        CHILD_A {
            @Override
                public InnerChild getInstance() {
                    return new InnerChildA();  // compile error
                }
        },
        CHILD_B {
            @Override
                public InnerChild getInstance() {
                    return new SampleParent.InnerChildB();  // compile error
                }
        },
        CHILD_C {
            @Override
                public InnerChild getInstance() {
                    return SampleParent.new InnerChildC();  // compile error
                }
        },
        ;

        public abstract InnerChild getInstance();
    }

    private static class InnerChildFactoryEnumStyled {
        public static InnerChild getInnerChild(InnerChildEnum child) {
            return child.getInstance();
        }
    }


    public static void main(String[] args) {

        // I want to write this way
        InnerChild child = InnerChildFactoryEnumStyled.getInnerChild(InnerChildEnum.CHILD_A);
    }
}
Run Code Online (Sandbox Code Playgroud)

编译错误消息如下

$ javac SampleParent.java 
SampleParent.java:12: error: non-static variable this cannot be referenced from a static context
                return new InnerChildA();
                       ^
SampleParent.java:18: error: non-static variable this cannot be referenced from a static context
                return new SampleParent.InnerChildB();
                       ^
SampleParent.java:24: error: cannot find symbol
                return SampleParent.new InnerChildC();
                       ^
  symbol: variable SampleParent
3 errors
Run Code Online (Sandbox Code Playgroud)

Ste*_*ski 5

您的内部类不是静态的,因此它们必须引用封闭类的实例SampleParent.将您的类声明更改为

private static class InnerChild { }
private static class InnerChildA extends InnerChild { }
private static class InnerChildB extends InnerChild { }
private static class InnerChildC extends InnerChild { }
Run Code Online (Sandbox Code Playgroud)

你可以return new InnerChildA();在你的枚举中.


dav*_*xxx 3

要实例化非静态内部类(InnerChildAInnerChildB等...),您需要使用封闭类型(SampleParent)的实例来限定实例化。你必须做这样的事情: new ExternalClass().new InternalClass()

在您的情况下,您可以在枚举SampleParent中声明并实例化一个静态实例,并在枚举值声明的InnerChildEnum每个实现方法中重用它。getInstance()

private class InnerChild {
}

private class InnerChildA extends InnerChild {
}

private class InnerChildB extends InnerChild {
}

private class InnerChildC extends InnerChild {
}

enum InnerChildEnum {

    CHILD_A {
        @Override
        public InnerChild getInstance() {
            return sampleParent.new InnerChildA();
        }
    },
    CHILD_B {
        @Override
        public InnerChild getInstance() {

            return sampleParent.new InnerChildB(); // compile error
        }
    },
    CHILD_C {
        @Override
        public InnerChild getInstance() {
            return sampleParent.new InnerChildC();
        }
    };

    private static SampleParent sampleParent = new SampleParent();

    public abstract InnerChild getInstance();
}
Run Code Online (Sandbox Code Playgroud)