如何在Java中使用枚举复制构造函数?

时间:2011-10-26 03:19:21

标签: java enums copy copy-constructor

我正在尝试完成一个项目,虽然我已经尝试过,但我似乎无法做到这一点。这是枚举:

public enum Symbols {
    /**
     * The Seven
     */
    SEVEN(12,"images/seven.jpg"),
    /**
     * The Watermelon
     */
    WATERMELON(10,"images/watermelon.jpg"),
    /**
     * The Orange
     */
    ORANGE(8,"images/orange.jpg"),
    /**
     * The Plum
     */
    PLUM(6,"images/plum.jpg"),
    /**
     * The Lemon
     */
    LEMON(4,"images/lemon.jpg"),
    /**
     * The Cherry
     */
    CHERRY(2,"images/cherry.jpg");

    private int payout;             // Symbol payout value
    private BufferedImage image;    // Symbol image
    private String icon;            // Symbol file name

    /** Constructor - Payout must be positive and even, file name must not be null
     * @param payout - Symbol payout amount
     * @param icon - Symbol image file name
     */
    Symbols(int payout, String icon){
        this.payout = payout;
        this.icon = icon;
        loadImage(icon);
    }

    /** Copy Constructor - Symbol must not be null
     * @param s - A single symbol
     */
    Symbols(Symbols s){
        payout = s.payout;
        icon = s.icon;
        loadImage(icon);
    }

现在我可以进入main并创建一个名为“s”的符号,如下所示:

Symbols s = Symbols.CHERRY;

但是我无法使用给定的复制构造函数制作“s”的副本:

Symbols t = Symbols(s);

如果我尝试这样做,我会收到错误:“Symbols类型的方法符号(符号)未定义。”

由于

6 个答案:

答案 0 :(得分:4)

嗯,你需要公开它,但它仍然不会起作用。 Java中没有复制构造函数;你不能'新'一个枚举,这是下一个错误;在任何情况下,Java都竭尽全力确保每个JVM每个枚举值只有一个副本。你认为你到底需要一个复制构造函数

解决方案:

Symbols s = Symbols.CHERRY;
Symbols t = s;

答案 1 :(得分:2)

枚举应该是一个不可变的集合 - 你不应该能够制作新的集合。并且构造函数被强制为私有(即使没有标记为私有)。

因为它们是不可变的,所以总是应该保证,如果你有一个Symbols.CHERRY对象的实例,它总是相同的实例,所以你可以做一些事情,比如测试对象等价而不是equals - 即你可以做

if (symbol == CHERRY) 

而不是

if (symbol.equals(CHERRY))

因为如果你有CHERRY,他们肯定是同一个对象。

这更倾向于成为Typesafe Enum模式的强制版本:

public class Suit {
    private final String name;

    public static final Suit CLUBS =new Suit("clubs");
    public static final Suit DIAMONDS =new Suit("diamonds");
    public static final Suit HEARTS =new Suit("hearts");
    public static final Suit SPADES =new Suit("spades");    

    private Suit(String name){
        this.name =name;
    }
}

答案 2 :(得分:2)

好吧,只有在调用new关键字时才会调用构造函数:

Symbols t = new Symbols(s);

如果没有new,则认为您正在尝试调用名为Symbols的方法。

但是在这种情况下这是无关紧要的,因为你无法在常量定义之外实例化枚举。如果可以,那就不是一个枚举。

让我们来看看为什么你想要拥有枚举的副本。如果你需要一份副本,那肯定是因为你说的是​​枚举是有状态的,这一定不是真的。枚举必须是不可变的。由于它们必须是不可变的,因此您可以在任何地方共享实例。

答案 3 :(得分:1)

你使用这样的ENUM:

public enum Symbols {
    SEVEN(12,"images/seven.jpg"),
    WATERMELON(10,"images/watermelon.jpg");

    private int payout;
    private String icon;

    Symbols(int payout, String icon){
        this.payout = payout;
        this.icon = icon;
    }

    public int getPayout(){
        return this.payout;
    }

    public String getIcon(){
        return this.icon;
    }
    public static void main(String[] args){
        System.out.println(Symbols.SEVEN.getPayout());
    }
}

其他答案很好地解释了为什么你不能拥有复制构​​造函数。基本上,枚举类的“实例”(SEVEN和WATERMELON)是不可变的,因此您不能在运行时指定其中的任何其他值,也不能创建新值。

答案 4 :(得分:0)

枚举不是普通的类。你不能手动构建它们。枚举“类”本身基本上是一个“抽象”类。每个值都作为枚举“class”的单独特定子类实现。

答案 5 :(得分:0)

枚举是不允许创建新对象的类。所以你的Symbol类(枚举)只有六个实例。您不能调用枚举构造函数,但可以拥有为这六个实例创建的引用的副本。

Symbols s = Symbols.CHERRY; //Get a copy of reference for instance CHERRY

另一方面,如果你想在Java中使用高级构造函数,则需要使用关键字“new”。