2010-12-10 33 views
117

Sau đây là đoạn trích về cách tạo một lớp chung Java để nối thêm một mục vào một mảng. Làm thế nào tôi có thể làm appendToArray một phương thức tĩnh. Thêm tĩnh vào chữ ký phương thức sẽ dẫn đến lỗi biên dịch.Làm thế nào để làm cho một phương pháp chung Java tĩnh?

public class ArrayUtils<E> { 

     public E[] appendToArray(E[] array, E item) { 
      E[] result = (E[])new Object[array.length+1]; 
      result[array.length] = item; 
      return result; 
     } 
} 
+0

Bạn nhận được lỗi biên dịch nào? Ngoài ra, tại sao không chỉ sử dụng một trong các thùng chứa thư viện chuẩn? –

+1

Biên dịch lỗi: Tôi đã thực sự thêm sửa đổi tĩnh không chính xác .. Sử dụng Bộ sưu tập: Có sử dụng một bộ sưu tập sẽ là lý tưởng nhưng câu hỏi không phải là về bộ sưu tập vs mảng, trường hợp sử dụng của tôi yêu cầu một mảng. –

+0

Lưu ý rằng bạn sẽ cần phải sử dụng (EVIL) phản ánh để ngăn chặn mã máy khách ném một ngoại lệ trong một số nhưng không phải tất cả các trường hợp (tốt đẹp). Tốt nhất là tránh các mảng tham chiếu. –

Trả lời

210

điều duy nhất bạn có thể làm là thay đổi chữ ký của bạn để

public static <E> E[] appendToArray(E[] array, E item) 

chi tiết quan trọng:

biểu Generic trước giá trị trả về luôn giới thiệu (tuyên bố) một generic kiểu mới biến.

Ngoài ra, hãy nhập các biến giữa các loại (ArrayUtils) và các phương pháp tĩnh (appendToArray) không bao giờ gây trở ngại cho nhau.

Vì vậy, những gì hiện này có nghĩa là: Trong câu trả lời của tôi <E> sẽ ẩn E từ ArrayUtils<E> nếu phương pháp này sẽ không được static. VÀ <E> không liên quan gì đến số E từ ArrayUtils<E>.

Để phản ánh thực tế này tốt hơn, một câu trả lời chính xác hơn sẽ là:

public static <I> I[] appendToArray(I[] array, I item) 
+16

Cũng xin lưu ý rằng hoàn toàn không có mối quan hệ giữa biến loại cấp lớp 'E' và biến kiểu phương thức tĩnh' E'. Tôi xem xét thực hành tốt hơn nhiều để sử dụng một tên biến khác nhau khi khai báo các phương thức generic, static hoặc cách khác, bên trong các lớp generic. –

+0

nhưng trong trường hợp này tôi có thể vượt qua một đối tượng của các loại khác nhau vào các tham số. Giống như tôi có thể vượt qua Integer [] mảng như param đầu tiên và mục đôi. – pinkpanther

+0

pinkpanther: Đúng, nhưng nó không gây hại gì, bởi vì phương thức tĩnh chỉ hoạt động trên một đối tượng mảng được truyền cho nó thông qua một tham số, vì vậy các phần tử của nó chắc chắn có kiểu đúng. – Dabbler

7

Bạn cần phải di chuyển tham số kiểu đến mức phương pháp để chỉ ra rằng bạn có một phương pháp chung chung chứ không phải là lớp generic:

public class ArrayUtils { 
    public static <T> E[] appendToArray(E[] array, E item) { 
     E[] result = (E[])new Object[array.length+1]; 
     result[array.length] = item; 
     return result; 
    } 
} 
57
public static <E> E[] appendToArray(E[] array, E item) { ... 

Lưu ý <E>.

Phương pháp chung chung tĩnh cần khai báo chung chung của riêng mình (public static <E>) tách biệt khỏi khai báo chung của lớp học (public class ArrayUtils<E>).

Nếu trình biên dịch phàn nàn về một loại mơ hồ trong việc gọi một phương thức chung chung (không có khả năng trong trường hợp của bạn, nhưng, nói chung, chỉ trong trường hợp), đây là cách gọi một phương thức tĩnh chung bằng cách sử dụng một kiểu cụ thể (_class_.<_generictypeparams_>_methodname_):

String[] newStrings = ArrayUtils.<String>appendToArray(strings, "another string"); 

Điều này sẽ chỉ xảy ra nếu trình biên dịch không thể xác định loại chung vì, ví dụ: loại chung không liên quan đến các đối số phương thức.

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