阴影类型参数

时间:2016-05-23 08:52:32

标签: java

我有一个关于类型参数的基本问题,这是我在解决问题时遇到的。

我有一个带有字符串数组的类,我使用自定义Comparator类进行排序。下面是我的Comparator类

class SortComparator implements Comparator<String>
    {

        @Override
        public int compare(String o1, String o2) {
            // TODO Auto-generated method stub
            return  o1.compareTo(o2);
        }

    }

上面的类运行正常并输出所需的结果。

如果班级名称从SortComparator更改为SortComparator<String>,则需要更改比较方法。更改后的类看起来像这样

class SortComparator<String> implements Comparator<String>
{

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        return  ((java.lang.String) o1).compareTo((java.lang.String) o2);
    }

}

上述类也运行良好并输出所需的结果

为什么当String个对象o1 o2java.lang.String已经是同一个类的对象时,需要明确地将它们转换为shadowing

我在网上搜索了一段时间的查询,发现了一个非常相似的问题

Comparing two Integers with my own Comparator

这个问题的答案是因为SELECT COL1 ,COL2 FROM TABLE1 WHERE COL2 IN ( CASE WHEN $EXTERNAL_PARAMETER = '' THEN COL2 ELSE $EXTERNAL_PARAMETER END)

我知道局部变量,实例变量和类变量方面的阴影,但在这种情况下它是如何工作的?

1 个答案:

答案 0 :(得分:7)

问题在于名为String的泛型类型。它是泛型类型参数和实际类String之间的冲突。

因为类型参数String无界,所以Java编译器将其替换为Object,因此方法compare的参数可用作Object和对象类没有compareTo方法,因此你必须强制转换。

尝试以下示例,该工作正常。

class SortComparator<T> implements Comparator<String>
{

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        return  o1.compareTo(o2);
    }

}

请查看Erasure of Generic Types

上的Java文档
  

在类型擦除过程中,Java编译器会擦除所有类型参数,如果type参数是有界的,则将每个参数替换为第一个绑定,如果type参数是无界的,则替换为Object。

下面的示例直接从上面的Java文档中复制,以便更清晰。

考虑以下用于表示单链表中节点的泛型类:

public class Node<T> {

    private T data;
    private Node<T> next;

    public Node(T data, Node<T> next) }
        this.data = data;
        this.next = next;
    }

    public T getData() { return data; }
    // ...
}

因为类型参数T是无界的,所以Java编译器将其替换为Object:

public class Node {

    private Object data;
    private Node next;

    public Node(Object data, Node next) {
        this.data = data;
        this.next = next;
    }

    public Object getData() { return data; }
    // ...
}