0

我目前正在以下页面上关注 Java 泛型的示例:http: //docs.oracle.com/javase/tutorial/java/generics/types.html

public interface Pair<K, V> {
    public K getKey();
    public V getValue();
}

public class OrderedPair<K, V> implements Pair<K, V> {

    private K key;
    private V value;

    public OrderedPair(K key, V value) {
    this.key = key;
    this.value = value;
    }

    public K getKey()   { return key; }
    public V getValue() { return value; }
}


Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);

我的问题是关于最后创建变量的行。一开始,一个从 pair 接口开始,而另一个从 OrderedPair 类开始。使用哪一个有区别吗?我只是想了解为什么代码不同。

4

3 回答 3

2

代码无效。Java 不允许在同一个作用域中有两个同名的变量。

如果名称是p1and p2,则它们中的每一个都引用了 class 的不同对象OrderedPair<String,Integer>。在第二种情况下,您可以省略通用参数,new因为它们已经用变量的类型指定(OrderedPair<String, Integer>在变量名之前)。在第一种情况下,对象的类型是变量类型的子类。这对每个多态性都是有效的。泛型参数被指定了两次,这也是有效的,尽管是多余的。

如上所述,p1p2类型的引用对象OrderedPair<String,Integer>。但是,p1p2具有不同的静态(声明)类型。在这种情况下,这意味着:

  1. 如果 typeOrderedPair有一个方法reverseOrder(只是说一些东西)不是从 继承的Pair,那么p1.reverseOrder()将是无效的(即使引用的对象是正确的类型,但编译器不知道这一点),但p2.reverseOrder()会是。在这里,p2“比”更好p1(因为您需要更多的特异性并且p2拥有它)。
  2. 如果您定义了第三种类型UnorderedPait implements Pair,则可以将这种类型的新实例分配给p1,但不能分配给p2。在这里,p1“比”更好p2(因为您需要更多的通用性并且p1拥有它)。
于 2013-09-01T00:03:24.257 回答
0

第一个使用 Pair 的引用。有了这个,您可以指向 Pair 接口的任何实现 - OrderedPair、SortedPair、LongPair 等。

但是使用第二个引用,您只能指向 OrderedPair 的对象

于 2013-09-01T00:02:32.773 回答
0

如果OrderedPair类中有没有在接口中列出的方法Pair,那么您需要一个类型的表达式OrderedPair才能调用它们。换句话说,您希望将变量声明为OrderedPair,然后调用该变量的方法。另一方面,如果您只使用Pair接口中列出的方法,那么您可以将变量声明为 a Pair,然后调用其上的方法。您可能想要执行后者的原因有两个。

  • 一个类型的变量Pair可以引用其他实现的类的对象Pair——你可能有UnorderedPairPrettyPair等等,它们不是OrderedPair.
  • 它告诉您程序的未来维护者您只使用该Pair变量的方法 - 不会使用任何特定于的方法OrderedPair
于 2013-09-01T00:22:02.257 回答