我有一个关于类型参数的基本问题,这是我在解决问题时遇到的。
我有一个带有字符串数组的类,我使用自定义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
o2
和java.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)
。
我知道局部变量,实例变量和类变量方面的阴影,但在这种情况下它是如何工作的?
答案 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);
}
}
上的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; }
// ...
}