Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 调用泛型类型_Java_Variables_Generics - Fatal编程技术网

Java 调用泛型类型

Java 调用泛型类型,java,variables,generics,Java,Variables,Generics,我目前正在下面的页面上学习Java泛型的示例: 公共接口对{ 公共K getKey(); public V getValue(); } 公共类OrderedPair实现了Pair{ 私钥; 私人价值; 公共OrderedPair(K键,V值){ this.key=key; 这个值=值; } public K getKey(){return key;} public V getValue(){return value;} } 对p1=新订购的对(“偶数”,8); OrderedPair p1=新

我目前正在下面的页面上学习Java泛型的示例:

公共接口对{
公共K getKey();
public V getValue();
}
公共类OrderedPair实现了Pair{
私钥;
私人价值;
公共OrderedPair(K键,V值){
this.key=key;
这个值=值;
}
public K getKey(){return key;}
public V getValue(){return value;}
}
对p1=新订购的对(“偶数”,8);
OrderedPair p1=新的OrderedPair(“偶数”,8);

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

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


但是对于第二个引用,您只能指向OrderedPair的对象,因为代码无效。Java不允许在同一范围内使用两个同名变量

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

如上所述,
p1
p2
都引用了
OrderedPair
类型的对象。但是,
p1
p2
具有不同的静态类型。在这种情况下,这意味着:

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

  • 如果
    OrderedPair
    类中有一些方法未在
    Pair
    接口中列出,则需要类型为
    OrderedPair
    的表达式才能调用它们。换句话说,您希望将变量声明为
    OrderedPair
    ,然后调用该变量的方法。另一方面,如果您只使用
    Pair
    接口中列出的方法,那么您可以将变量声明为
    Pair
    ,并对其调用方法。有两个原因可以让你选择后者

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

    • 语法进行类型推断:(如果这是你要问的。还不清楚你的意思有什么不同。)@millimoose所以在看到你的评论之前我想了几毫秒。“这对于每个多态性都是有效的,但是强制您指定两次泛型参数。”这是不正确的,尽管OP的代码似乎就是这样<代码>列表字符串=新建ArrayList()工作。(事实上,更复杂的情况是:)@millimoose更正完成。谢谢你的关注。
      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);