2008-09-01 45 views
9

Có cách viết tắt nào để xác định và sử dụng loại bỏ chung mà không phải lặp lại một mô tả chung đặc biệt sao cho nếu có thay đổi, tôi không phải thay đổi tất cả các definations/usages. được somethhing như thể này:Generics trong Java

Typedef myGenDef = < Object1, Object2 >; 

HashMap<myGenDef> hm = new HashMap<myGenDef>(); 

for (Entry<myGenDef> ent : hm..entrySet()) 
{ 
. 
. 
. 
} 

Trả lời

11

có những pseudo-typedef antipattern ...

class StringList extends ArrayList<String> { } 

Thứ tốt, uống đi! ;-)

Khi ghi chú bài viết, kỹ thuật này có một số vấn đề nghiêm trọng, chủ yếu là "typedef" này thực sự là một lớp riêng biệt và do đó không thể được sử dụng thay thế lẫn nhau với loại mở rộng hoặc các loại được xác định tương tự khác.

+0

Bạn có thể không chấp nhận một mẫu giải thích cho câu hỏi của mình, đặc biệt khi có các giải pháp thay thế. Nhưng nếu nó giúp bạn ra ngoài với vấn đề cụ thể của bạn ... –

+0

(Bỏ qua lời khuyên của người kiểm duyệt về tiếng ồn trên các chủ đề "typedef trong Java") ... Điều đó còn tồi tệ hơn một mẫu chống. Nó tạo ra một kiểu hạng nhất mới, với các mục riêng của nó trong các bảng phương thức ảo và tất cả các nghĩa vụ như vậy.Một kiểu gõ C++ chỉ đơn thuần là làm cho phần "ArrayList " một phần DRY, vì vậy bạn có thể thay đổi String (hoặc ArrayList) chỉ ở một nơi. – Phlip

+0

Có, kiểu chữ C/C++ là một tính năng ngôn ngữ được tôn trọng với sự hỗ trợ tốt và nhiều công dụng hợp pháp. Đây không phải là. Do đó toàn bộ "antipattern" điều. – Shog9

1

số Mặc dù, groovy, một ngôn ngữ JVM, được tạo kiểu động và sẽ cho phép bạn viết:

def map = new HashMap<complicated generic expression>(); 
+0

Giống với Scala. Các ngôn ngữ này cung cấp cú pháp có thể suy ra các kiểu từ các câu lệnh khởi tạo biến. Điều này tương tự như những gì được cung cấp trong .NET với từ khóa var. Đừng nhầm lẫn điều này với ngôn ngữ đánh máy yếu (hoặc lỏng lẻo) cho phép bạn có cơ hội một loại biến trên bay; JVM vẫn thực thi gõ mạnh mẽ trong mã được biên dịch của nó. –

4

Trong một phương pháp chung, bạn có thể sử dụng hình thức loại inferrence hạn chế để tránh một số sự lặp lại.

Ví dụ: nếu bạn có chức năng

<K, V> Map<K, V> getSomething() { 
     //... 
    } 

bạn có thể sử dụng:

final Map<String, Object> something = getsomething(); 

thay vì:

final Map<String, Object> something = this.<String, Object>getsomething(); 
3

Sử dụng Factory Pattern để tạo Generics:

Phương thức mẫu:

public Map<String, Integer> createGenMap(){ 
     return new HashMap<String,Integer>(); 

    } 
2

Mẫu giả dạng pseudo-typedef được đề cập bởi Shog9 sẽ hoạt động - mặc dù nó không được khuyến khích sử dụng ANTIPATTERN - nhưng nó không đề cập ý định của bạn. Mục tiêu của pseudo-typedef là giảm sự lộn xộn trong khai báo và cải thiện khả năng đọc.

Điều bạn muốn là có thể thay thế một nhóm các khai báo Generics bằng một giao dịch duy nhất. Tôi nghĩ rằng bạn phải dừng lại và suy nghĩ: "theo cách phù thủy là nó có giá trị?". Ý tôi là, tôi không thể nghĩ ra một kịch bản mà bạn sẽ cần đến điều này. Hãy tưởng tượng lớp A:

class A { 
    private Map<String, Integer> values = new HashMap<String, Integer>(); 
} 

Hãy tưởng tượng bây giờ tôi muốn thay đổi trường 'giá trị' thành Bản đồ. Tại sao tồn tại nhiều lĩnh vực khác được phân tán qua mã cần thay đổi tương tự? Đối với các hoạt động sử dụng 'giá trị', việc tái cấu trúc đơn giản là đủ.