Java 为什么方法签名会有这种差异?

Java 为什么方法签名会有这种差异?,java,api,generics,Java,Api,Generics,由此: 1) 下面是树映射的构造函数,它获取另一个映射并使用(传递的映射的)可比较接口对其进行排序 2) 下面是树映射的构造函数,它接受另一个映射并使用(传递的映射的)比较器接口对其进行排序 树形图 public TreeMap(SortedMap<K,? extends V> m) Constructs a new tree map containing the same mappings and using the same ordering as the specified

由此:

1) 下面是树映射的构造函数,它获取另一个映射并使用(传递的映射的)可比较接口对其进行排序

2) 下面是树映射的构造函数,它接受另一个映射并使用(传递的映射的)比较器接口对其进行排序

树形图

public TreeMap(SortedMap<K,? extends V> m)

Constructs a new tree map containing the same mappings and using the same ordering as the specified sorted map. This method runs in

为什么第一个签名是
public TreeMap(Map两者都是有效的构造函数,但是作为惯例,您应该始终使用您能使用的最高接口。因此,尽管获取Map的构造函数在所有情况下都可以工作,但当您从SortedMap构建TreeMap时,您应该使用SortedMap构造函数


但为什么会在这种情况下呢?因为通过让构造函数知道您传递的不是常规映射,而是已排序的映射,它可能会利用它并以最佳方式运行。在这种特殊情况下,很容易理解为什么要构建树映射(这是一个已排序的映射)从一个已经排序的映射中创建要比从一个没有排序的映射(如Hasmap)中创建要快:构造器必须先订购地图,但它会跳过已订购地图上的这一部分,因为它已经订购。

构造器使用
?扩展K
,因为尽可能使其松散总是好的

SortedMap
构造函数使用
K
,因为它使用另一个map的比较器,如果边界是
?扩展K
,则不会进行类型检查

让我更详细地解释一下

假设我们有类
Base
Middle-extends-Base
,以及
派生的extends-Middle实现了Foo

然后我们有两个特殊的比较器,
BaseComp实现比较器
FooComp实现比较器

现在我们创建一个
TreeMap
,并给它一个
FooComp

SortedMap<Derived, String> sm1 = new TreeMap<Derived, String>(new FooComp());
同样,这很好。
BaseComp
实现
Comparator
Base super-Derived
类型检查


好的,让我们进一步假设接受排序映射的构造函数具有签名
TreeMap(SortedMapI更关心泛型。为什么在第一个K是?扩展了K,在第二个是KYour edit是不正确的。这与强制它实现Comparable无关。确实是这样,你的回答很好地解释了这一部分。删除了我的编辑并对你的进行了升级。
public TreeMap(SortedMap<K,? extends V> m)

Constructs a new tree map containing the same mappings and using the same ordering as the specified sorted map. This method runs in
Parameters:
    m - the sorted map whose mappings are to be placed in this map, and whose comparator is to be used to sort this map
Throws:
    NullPointerException - if the specified map is null
SortedMap<Derived, String> sm1 = new TreeMap<Derived, String>(new FooComp());
SortedMap<Derived, String> sm2 = new TreeMap<Derived, String>(new BaseComp());
SortedMap<Middle, String> sm3 = new TreeMap<Middle, String>(sm2);
SortedMap<Middle, String> sm4 = new TreeMap<Middle, String>(sm1);
public interface SortedMap<K1, V1> extends Map<K1, V1> {
    Comparator<?1 super K1> comparator();
}
public class TreeMap<K2, V2> ... {
    private Comparator<?2 super K2> comp;

    public TreeMap(SortedMap<?3 extends K2, ?4 extends V2> map) {
        this.comp = map.comparator();
        // magic stuff to transfer elements
    }
}