调用泛型类型

时间:2013-08-31 23:59:08

标签: java variables generics

我目前正在关注以下页面上关于Java的Generics的示例: 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);

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

3 个答案:

答案 0 :(得分:2)

代码无效。 Java不允许在同一范围内使用两个相同名称的变量。

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

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

  1. 如果类型OrderedPair有一个方法reverseOrder(只是说某事)不是从Pair继承的,那么p1.reverseOrder()将无效(即使引用的对象是正确的类型,但编译器不知道这一点),但p2.reverseOrder()将是。在这里,p2“比p1更好”(因为您需要更多的特异性而p2拥有它)。
  2. 如果您定义了第三种类型UnorderedPait implements Pair,则可以将此类型的新实例分配给p1,但不能分配给p2。在这里,p1“比p2更好”(因为您需要更多的通用性,而p1有更多的一般性。)

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

如果OrderedPair类中的方法未在Pair界面中列出,那么您需要一个类型为OrderedPair的表达式才能给他们打电话。换句话说,您希望将变量声明为OrderedPair,然后调用该变量上的方法。另一方面,如果您仅使用Pair界面中列出的方法,则可以将变量声明为Pair,并在其上调用方法。你可能想要做后者有两个原因。

  • 类型Pair的变量可以引用实现Pair的其他类的对象 - 您可能有UnorderedPairPrettyPair等等,它们不是{的子类{1}}。
  • 它告诉您的程序的未来维护者您只使用该变量的OrderedPair方法 - 任何特定于Pair的方法都不会被使用。