在java方法中使用泛型时如何正确转换?

时间:2012-02-01 19:46:56

标签: java generics

我有一个分配来实现我自己的Collections.fill()和Collections.reverse()版本。这些算法很简单,但我在涉及的泛型中有点迷失,特别是当我需要进行转换时。

我最初的想法是:

public static void reverse(List<?> a_list) {
    int list_size = a_list.size();
    ListIterator<?> left_to_right = a_list.listIterator();
    ListIterator<?> right_to_left = a_list.listIterator(list_size);
    ? temp_variable;

    // ..doing some stuff

    right_to_left.set(temp_variable);

}

但当然我不能将temp声明为“?”类型。声明为“对象temp_variable”是有道理的,但是最后调用set(temp_variable)将不起作用(因为ListIterator不会使用Object - 因为列表可能不是类型List&lt; Object&gt;)。 / p>

对我有意义,然后将temp声明为Object,并强制转换ListIterators:

ListIterator<Object> left_to_right = 
    (ListIterator<Object>) a_list.listIterator();
ListIterator<Object> right_to_left = 
    (ListIterator<Object>) a_list.listIterator(list_size);

编译器在我这样做时给了我未经检查的强制警告,但考虑到我的实现,我无法想到它会如何破坏。这样做有危险吗?

然后在Collections.fill()中,我原本想做类似的事情:

public static <E> void fill(List<? super E> a_list, E an_object) {
    ListIterator<E> an_iterator = (ListIterator<E>) a_list.listIterator();

            // ..doing some stuff
    an_iterator.set(an_object);

}

这也给出了未经检查的投射警告。并且考虑更多,即使我仍然得到警告,做一个类似的演员会更安全:

ListIterator<Object> an_iterator = (ListIterator<Object>)a_list.listIterator();

如果列表的泛型类型实际上是E的超类,那么为了列表的对象而转换为ListIterator,而不是列表的泛型类的子类的ListIterator应该更安全,不应该?

任何建议都会受到赞赏......我认为我们的导师不希望我们参与其中,但我想更好地理解泛型。

2 个答案:

答案 0 :(得分:6)

不要施放,也不要使用?。使用类型参数化方法;像这样的东西。

public static <T> void reverse(List<T> a_list) {
    int list_size = a_list.size();
    ListIterator<T> left_to_right = a_list.listIterator();
    ListIterator<T> right_to_left = a_list.listIterator(list_size);
    T temp_variable;

    while(left_to_right.nextIndex() < list_size / 2) {
        temp_variable = left_to_right.next();
        left_to_right.set(right_to_left.previous());
        right_to_left.set(temp_variable);
    }
}

答案 1 :(得分:3)

如果您拥有Xyz<?>形式的泛型类型,那么?将代表某种特定(但不一定是可表示的)类型。 (对于Abc<Xyz<?>>,情况并非如此。)方法调用可以推断类型,这使我们能够使用“捕获助手”方法为类型赋予标签(感谢@newacct)。

public static void reverse(List<?> list) {
    reverseImpl(list);
}
private static <T> void reverseImpl(List<T> list) {

您现在可以将本地人定义为T类型。

相关问题