2011-10-26 45 views
4

我正在尝试完成一个项目,尽管我已经尝试过了,但我似乎无法做到这一点。这里的枚举:如何在Java中使用枚举拷贝构造函数?

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); 
    } 

现在我可以进入主并创建一个名为“S”这样的符号:

Symbols s = Symbols.CHERRY; 

但我有麻烦的“S”副本使用复制构造函数给出:

Symbols t = Symbols(s); 

如果我试图做到这一点,我得到的错误:“该方法符号(符号)是未定义的类型符号。

谢谢

回答

0

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

4

那么你需要把它公开,但它仍然不会工作。 Java中没有拷贝构造函数;你不能'新'一个枚举,这是下一个错误;无论如何,Java会竭尽全力确保每个JVM只有每个枚举值的一个副本。你认为你究竟需要一个拷贝构造函数

解决方案:

Symbols s = Symbols.CHERRY; 
Symbols t = s; 
+0

那么如果你定义了它们(他完成了),那么就有复制构造函数。 –

+0

@MarkPeters,但编译器不会*使用*它们,除非你自己调用它们。例如,他给出的代码不会编译,如果他写了't = s;'编译器不会自动调用复制构造函数。我不称之为复制构造函数。只是一个构造函数。 – EJP

+0

你是对的,它不是一个复制构造函数,因为有隐式调用它的语法(就像我认为C++会)。但我认为调用一个将其自己的类的实例作为“复制构造函数”的构造函数仍然是常见做法。 –

2

枚举应该是一个不变的集 - 你不应该是能够结交新朋友。而构造函数被强制执行为私有(即使没有标记为这样)。

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

if (symbol == CHERRY) 

代替

if (symbol.equals(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

好,构造函数只被调用,当你调用new关键字:

Symbols t = new Symbols(s); 

没有new它认为你试图调用名为Symbols的方法。

但这在这种情况下是不相关的,因为你不能在常量定义之外实例化枚举。如果可以的话,它不会是枚举。

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

0

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

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

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

1

您使用枚举是这样的:

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()); 
    } 
} 

其他的答案了,为什么你不能有拷贝构造函数一个很好的解释。基本上你的enum类的“实例”(SEVEN和WATERMELON)是不可变的,所以你不能在运行时指定任何其他的值,也不能创建新的值。