2012-02-04 26 views
21

Tôi muốn thực hiện một lớp chung của mẫu này:lớp Generic chấp nhận một trong hai loại

class MyGenericClass<T extends Number> {} 

Vấn đề là, tôi muốn được chấp nhận cho T để thể là Integer hay Long, nhưng không phải đôi. Vì vậy, hai tờ khai chỉ chấp nhận được sẽ là:

MyGenericClass<Integer> instance; 
MyGenericClass<Long> instance; 

Có cách nào để làm điều đó không?

Trả lời

22

Câu trả lời là không. Ít nhất không có cách nào để làm điều đó bằng cách sử dụng các loại chung chung. Tôi muốn giới thiệu một sự kết hợp của generics và phương pháp nhà máy để làm những gì bạn muốn.

class MyGenericClass<T extends Number> { 
    public static MyGenericClass<Long> newInstance(Long value) { 
    return new MyGenericClass<Long>(value); 
    } 

    public static MyGenericClass<Integer> newInstance(Integer value) { 
    return new MyGenericClass<Integer>(value); 
    } 

    // hide constructor so you have to use factory methods 
    private MyGenericClass(T value) { 
    // implement the constructor 
    } 
    // ... implement the class 
    public void frob(T number) { 
    // do something with T 
    } 
} 

Điều này đảm bảo rằng chỉ có MyGenericClass<Integer>MyGenericClass<Long> trường hợp có thể được tạo ra. Mặc dù bạn vẫn có thể khai báo một biến kiểu MyGenericClass<Double> nhưng nó sẽ phải là rỗng.

+0

Lợi ích của việc sử dụng chung chung ở đâu? Kể từ khi thực hiện một phương pháp có tham số của Type T sẽ chấp nhận bất kỳ số nào? –

+0

Trong mã của bạn, nó chắc chắn là không. Vì không thể viết phương thức chấp nhận tham số của Kiểu T. Bạn phải viết hai định nghĩa riêng biệt của từng phương thức như vậy, một cho Integer và một cho Long. –

+0

@djaqeel Điều đó không đúng. Nếu bạn cố gắng sử dụng phương pháp frob với một cái gì đó khác với một Long hoặc một số nguyên, bạn sẽ nhận được một ngoại lệ trình biên dịch. – luke

2

Không, không có gì trong Java Generics để cho phép điều này. Bạn có thể muốn xem xét việc có giao diện không chung chung, được triển khai bởi FooIntegerImplFooLongImpl. Thật khó để nói mà không biết nhiều hơn về những gì bạn đang cố gắng đạt được.

+0

Tôi đã nghĩ về điều đó và nó sẽ giải quyết được vấn đề của tôi. Tôi đã tự hỏi nếu Generics java cho phép tôi làm điều đó mà không cần phải khai báo các lớp học này. Nhưng tôi sẽ không sử dụng giao diện, bởi vì việc triển khai cả hai lớp là như nhau. Tôi sẽ tạo một lớp trừu tượng được bảo vệ lớp và tạo ra hai lớp công khai mở rộng nó. – Rafael

+0

Và đối với những gì tôi đang cố gắng đạt được, tôi muốn tạo ra một lớp có ý nghĩa cho Integer, Long hoặc bất kỳ kiểu int nào khác, nhưng nó không có ý nghĩa khi sử dụng nó với các kiểu dấu phẩy động. – Rafael

Các vấn đề liên quan