2011-07-19 24 views
23

Tôi đang cố gắng viết một phương thức chung để trả về nội dung của một dạng Iterable trong mảng.Phương pháp tái sử dụng để chuyển đổi Iterable <T> thành T []?

Dưới đây là những gì tôi có:

public class IterableHelp 
{ 
    public <T> T[] toArray(Iterable<T> elements) 
    { 
     ArrayList<T> arrayElements = new ArrayList<T>(); 
     for(T element : elements) 
     { 
      arrayElements.add(element); 
     } 

     return (T[])arrayElements.toArray(); 
    } 
} 

Nhưng tôi nhận được một cảnh báo trình biên dịch 'Lưu ý: ... \ IterableHelp.java sử dụng hoạt động đánh dấu hoặc không an toàn.'

Bất kỳ suy nghĩ nào về cách tiếp cận khác có thể tránh cảnh báo như vậy?

+2

Tôi cho rằng cảnh báo nằm trên dòng cuối cùng, nơi bạn đang truyền mảng đến 'T []'? – MatrixFrog

+0

@MatrixFrog chính xác – Dejas

+2

Xem thêm 'Iterables.toArray của Guava (Iterable , Class )' –

Trả lời

27

Có một phương pháp Iterables.toArray trong Google ổi.

Nhìn vào the source, nó được định nghĩa như sau:

/** 
    * Copies an iterable's elements into an array. 
    * 
    * @param iterable the iterable to copy 
    * @param type the type of the elements 
    * @return a newly-allocated array into which all the elements of the iterable 
    *  have been copied 
    */ 
    public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) { 
    Collection<? extends T> collection = toCollection(iterable); 
    T[] array = ObjectArrays.newArray(type, collection.size()); 
    return collection.toArray(array); 
    } 

đâu ObjectArrays.newArray cuối cùng các đại biểu đến một phương pháp mà trông giống như:

/** 
    * Returns a new array of the given length with the specified component type. 
    * 
    * @param type the component type 
    * @param length the length of the new array 
    */ 
    @SuppressWarnings("unchecked") 
    static <T> T[] newArray(Class<T> type, int length) { 
    return (T[]) Array.newInstance(type, length); 
    } 

Vì vậy, có vẻ như không có cách nào để tránh những @SuppressWarnings hoàn toàn, nhưng bạn có thể và ít nhất nên hạn chế nó đến phạm vi nhỏ nhất có thể.

Hoặc, tốt hơn, chỉ cần sử dụng triển khai của người khác!

2

Không có cách nào để loại bỏ cảnh báo unchecked or unsafe operations hoặc tạo một mảng TypeSafe mà không chỉnh sửa chữ ký phương thức của bạn.

Xem chi tiết bug report để biết chi tiết đẫm máu.

Một cách là để vượt qua trong một mảng được cấp phát trước của Loại T:

public class IterableHelp 
{ 
    public <T> T[] toArray(final T[] t, final Iterable<T> elements) 
    { 
     int i = 0; 
     for (final T element : elements) 
     { 
      t[i] = element; 
     } 
     return t; 
    } 
} 

này được thoát khỏi những cảnh báo unchecked or unsafe, nhưng nó cũng đặt trách nhiệm vào các lớp gọi điện thoại để tạo ra các mảng với giới hạn chính xác để bắt đầu với loại đánh bại mục đích của phương pháp tiện lợi của bạn.

Nếu bạn muốn tạo động một mảng TypeSafe, bạn thực sự không thể làm điều đó theo một cách TypeSafe trong Java.

Công việc này và biên dịch, nhưng nó không giải quyết được vấn đề đúc không được kiểm soát hoặc không an toàn, nó chỉ chuyển nó đến một nơi khác. Tôi phải thêm chú thích @SuppressWarnings để khiến chú thích ngừng phàn nàn về diễn viên.

@SuppressWarnings({"unchecked"}) 
public class IterableHelp 
{ 
    public <T> T[] toArray(Class<T> t, Iterable<T> elements) 
    { 
     final ArrayList<T> arrayElements = new ArrayList<T>(); 
     for (T element : elements) 
     { 
      arrayElements.add(element); 
     } 
     final T[] ta = (T[]) Array.newInstance(t, arrayElements.size()); 
     return arrayElements.toArray(ta); 
    } 
} 
0

Bạn gặp sự cố lớn hơn so với cảnh báo không được chọn. Trong thực tế, nó sẽ ném một ClassCastException vào thời gian chạy nếu T là bất kỳ thứ gì ngoài Object.

Hãy thử String[] foo = IterableHelp.toArray(new ArrayList<String>());

một cách đơn giản, vì mảng chứa các loại thành phần trong thời gian chạy, để tạo ra một hợp T [] bạn phải vượt qua trong lớp thành phần như là đối số khác (hoặc là lớp của T hoặc T [] chính nó, hoặc như một đối tượng của T hoặc T []), và sử dụng sự phản chiếu để tạo mảng. Các hình thức của Collection 's toArray() phương pháp mà có một đối số, mất trong một đối tượng T [] vì lý do này.

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