2009-09-15 8 views
7

Tôi có thể sai nhưng tôi đoán từ Why can't enums be declared locally in a method? rằng, vì một enum trong Java không thể được khai báo cục bộ, do đó nó là vấn đề cho một phương pháp để trả về kiểu Enum? Tôi có thể tuyên bố rằng một phương thức sẽ trả về một Enum (xem bên dưới) nhưng làm thế nào một người có thể thực hiện phương thức như vậy để trả về bất kỳ thứ gì khác null hoặc tham chiếu đến một Enum được khai báo bên ngoài phương thức? Độ nghiêng đầu tiên của tôi là điều tra bằng cách sử dụng Generics cho điều này nhưng tôi muốn tránh bất kỳ deadends nếu cộng đồng SO có thể giúp tôi tránh chúng.Các phương thức Java có thể trả về kiểu Enum không?

private Enum resources() { 
    return null; 
} 
+0

Bạn muốn trả về kiểu 'Enum', hoặc giá trị' Enum'? – jjnguy

+0

Tôi không chắc rằng tiêu đề của câu hỏi là phù hợp nhất. Bạn thực sự muốn làm gì? –

+0

Xin lỗi vì sự nhầm lẫn, và tôi có thể nhầm lẫn với những gì tôi đang cố gắng đạt được (suy nghĩ của tôi bắt đầu trở nên tồi tệ vào chiều muộn) nhưng tôi nghĩ tôi có thể có một phương thức trả về một Enum * không * thành viên chung từ một Enum. –

Trả lời

8

Tôi nghĩ bạn đã chính xác, nó chỉ có thể trả lại null hoặc Enum được khai báo ở một nơi khác. Nhưng bạn không nhất thiết phải xác định rằng "cái gì khác" tại thời gian biên dịch.

class EnumEnumerator<T extends Enum<T>> implements Iterable<T> { 
    private final Class<T> enumClass; 

    public EnumEnumerator(Class<T> enumClass) { 
     this.enumClass = enumClass; 
    } 

    public Iterator<T> iterator() { 
     T[] values = enumClass.getEnumConstants(); 
     return Arrays.asList(values).iterator(); 
    } 
    } 

Sau đó, bạn gọi nó bằng chuyên các nhà xây dựng chung và đi qua trong lớp enum bạn quan tâm:

class EnumEnumeratorDemo { 
    enum Foo { 
     BAR, BAZ, QUX; 
     @Override public String toString() { 
      return name().toLowerCase(); 
     } 
    } 

    public static void main(String[] args) { 
     for (Foo f : new EnumEnumerator<Foo>(Foo.class)) { 
      System.out.println(f); 
     } 
    } 
} 

(Rõ ràng đây là một ví dụ contrived và trong cuộc sống thực, bạn chỉ nên gọi Foo.values ​​(), nhưng bạn có ý tưởng.)

+0

bạn có thể vui lòng thêm cách sử dụng lớp này không? – msysmilu

+0

hoàn thành — hy vọng điều đó sẽ hữu ích. –

+1

p.s. để nhận được mảng giá trị bạn chỉ có thể làm 'values ​​= enumClass.getEnumConstants()' – newacct

2

Bạn đang cố gắng làm gì? Đây là một cách để trả lại một số Enum:

public class Test 
{ 
    public static void main(String args[]) 
    { 
     System.out.println(doit()); 
    } 

    public enum Foo { 
     BAR, 
     BAZ; 
    } 
    public static Enum doit() { 
     return Enum.valueOf(Foo.class,"BAR"); 
    } 
} 

Nhưng, tôi đoán đây không phải là điều bạn đang làm?

+1

Bạn muốn 'Enum '. –

+0

Thực ra, tôi không muốn bất kỳ mã nào trong số này; có vẻ như một điều kỳ lạ để làm gì cả :) – davetron5000

1

Vâng, chắc chắn là có thể.

private Enum getRetentionPolicy() { 
    return java.lang.annotation.RetentionPolicy.SOURCE; 
} 

Nếu câu hỏi của bạn là về tuyên bố Enums, bạn có thể khai báo:

  • trong file java riêng của họ, tương tự như một top-level class;
  • trong tệp java thuộc về một lớp khác, tương tự như bên trong tĩnh class;
1

Không hoàn toàn chắc chắn những gì mục tiêu của bạn, nhưng nếu bạn muốn trả về một phương pháp generified (tức là một trong đó sẽ được ghi đè), bạn có thể có một cái gì đó như sau:

public class MyEnumClass<T extends Enum<T>> { 
    public T resources() { 
     //do stuff here 
    } 
} 

Không hoàn toàn chắc chắn những gì bạn sẽ đạt được điều đó, mặc dù nó có thể có ích nếu bạn đang nói về các bộ Enums khác nhau và các yếu tố của chúng.

Nếu bạn đang nói về lớp Enum (tức là percursor to Iterator) theo như tôi biết nó đã không được phổ biến, vì vậy tôi không chắc chắn generics sẽ giúp nhiều ở đây.

1

Bạn có thể tham chiếu đến giá trị của một enum theo tên của nó, ví dụ: Suit.SPADES.

Bạn có thể lặp qua tất cả các giá trị bằng cách sử dụng phương thức values ​​() và chọn một trong các giá trị.

3

Tất cả các enums thực hiện giao diện Enum, vì vậy bạn chắc chắn có thể viết một phương thức trả về một enum theo cách này. Nhưng phương thức này sẽ trả về một giá trị enum duy nhất. Không có cách nào để trả về một giá trị chung chung bao gồm toàn bộ enum (ngoài việc trả về lớp và thực hiện sự phản chiếu). Tuy nhiên, bạn có thể trả lại tất cả các giá trị enum mà ít nhiều là những gì bạn muốn tôi nghĩ.

enum Resources { ONE, TWO, THREE } 
private Enum<?>[] resources() { 
    return Resources.values(); 
} 

Một lợi ích của phương pháp này là bạn có thể trả nhiều hơn hoặc ít hơn giá trị ví dụ:

enum Resources { ONE, TWO, THREE } 
enum MoreResources { UN, DEUX, TROIS } 
private Enum<?>[] resources() { 
    List<Enum<?>> resources = new ArrayList<Enum<?>>(); 
    resources.addAll(Arrays.asList(Resources.values()); 
    resources.addAll(Arrays.asList(MoreResources.values()); 
    return resources.toList(new Enum<?>[] {}); 
} 

Một cách tiếp cận tốt hơn đó là hơn typesafe là để có enums quan tâm thực hiện một giao diện chung ví dụ

Bạn có thể thêm phương thức bổ sung vào giao diện để cung cấp thêm chức năng.

3

Toàn bộ quan điểm của cách thức mà Java thực hiện là chúng an toàn - vì vậy bạn sẽ không trả về một Enum (có thể là gấp đôi), thay vào đó bạn trả về kiểu thực tế bạn định nghĩa (như "Suit")) hoạt động giống như một lớp học. Suit có 4 "Enumerated" trường hợp.

Nếu bạn đang mong đợi "Phù hợp", bạn có thể trả lại "Thứ hạng" là 7 khi nào? Nó sẽ phá vỡ mọi thứ!

Ngoài ra nếu bạn đã chuyển "Giá trị" hoặc một số giá trị chung chung, bạn không thể gọi các phương thức trên đó. Điều thú vị nhất về TypeSafe Enums là bạn chỉ có thể nhận được một "Suit" và gọi "Suit.getColor()" và hoàn toàn mong đợi để có được màu sắc của bộ đồ đó. Bạn cũng có thể có một ranksHigherThan (Suit s) mà có thể thực hiện:

assertTrue(SPADES.ranksHigherThan(HEARTS)); 

Hoặc, quan trọng hơn:

suit1.ranksHigherThan(suit2); 

(giả sử họ đã được cả hai được thông qua năm và bạn không biết những gì họ đang có)

Loại an toàn thực sự tuyệt vời (mặc dù lúc đầu cảm thấy hơi khó chịu), hãy ôm lấy nó.