【问题标题】:Why is it wrong to supply type parameter in the constructor of a generic class (Java)?为什么在泛型类 (Java) 的构造函数中提供类型参数是错误的?
【发布时间】:2015-08-31 05:21:25
【问题描述】:

我只是从一本教科书中学习 Java 中的泛型,它谈到了一个用 ArrayList<E> 实现的类 GenericStack<E>

因为为了创建一个字符串栈,你使用

GenericStack<String> = new GenericStack<String>()

GenericStack<String> new GenericStack<>()

因此不应该构造函数 GenericStack 定义为public GenericStack&lt;E&gt;(),还是public GenericStack&lt;&gt;()?答案是不。应该定义为public GenericStack()

这是为什么?显然构造函数可以很容易地从类声明中推断出类型,但是考虑到 Java 的冗长,我有点困惑为什么 &lt;E&gt; 或简单的 &lt;&gt; 形式在这里完全摆脱了。

【问题讨论】:

  • 再去了解java genric。 可用于包含许多方法的整个类。构造函数是其中一种方法,它可以使用,也可以不使用。

标签: java oop generics syntax constructor


【解决方案1】:

这有两个部分:

  1. 为类定义提供的泛型类型参数在类本身中可用。

  2. 您可以拥有特定于单个方法(包括构造函数)的泛型类型。

看下面的例子:

package snippet;

import java.util.ArrayList;

public class Y<E> extends ArrayList<E> {

    public <T> Y(T t) {
    }
}

由于E 类型对整个类都可用,T 类型仅在构造函数中有效。

【讨论】:

    【解决方案2】:

    类和构造函数都可以自己是泛型的,即每个都有自己的类型参数。例如

    class A<T>
    {
        <S>A(S s){}
    }
    

    使用所有显式类型参数调用构造函数

    new <String>A<Integer>("abc");  // T=Integer, S=String
    

    这样想,A&lt;Integer&gt; 是具体的类,&lt;String&gt;A 是具体的构造函数。

    由于类型推断,我们可以省略构造函数的类型参数

    new A<Integer>("abc");  // S=String is inferred
    

    类的类型参数也可以通过“菱形”(&lt;&gt;) 语法省略和推断

    A<Integer> a = new A<>("abc");  // T=Integer is inferred, as well as S=String
    

    我就这个主题写了一篇(长)帖子 - https://stackoverflow.com/a/32292707/2158288

    【讨论】:

      【解决方案3】:

      您将方法的声明与其调用站点(即您使用它的位置)混淆了。如果您想使用在类上声明的泛型,只需在调用站点提供&lt;E&gt;&lt;&gt; - 而不是 声明。在这方面,构造函数的声明与任何其他方法一样:

      public GenericStack<E> {
          public E get() { ...            // correct
          public <E> put(E element) { ... // bad (see below)
          public GenericStack() { ...     // correct, like the get()
      

      重新声明泛型(如上面的put 案例)实际上是遮蔽它; put(E) 中的 E 实际上与 GenericStack&lt;E&gt; 中的 E 不同,尽管名称相同。这很令人困惑,您应该避免这样做。

      【讨论】:

      • 我注意到所有新发布的属于 java 主题的问答都被否决了。有点奇怪。也许有人有意。
      • @J.Lyu 你还有其他例子吗?我查了几个帖子,没看到。
      • 只是我的猜测。暂时没有例子。其中大多数再次获得支持。当您搜索“java”时,您可能会看到大多数问题都投了反对票。也许他们实际上并不好。
      • OP 已经知道你所说的:显然构造函数可以很容易地从类声明中推断出类型
      • @SotiriosDelimanolis 好吧,我说的是声明站点,而不是调用站点。但我本来可以更清楚的;编辑它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-06
      • 2021-08-17
      • 1970-01-01
      • 1970-01-01
      • 2019-07-05
      相关资源
      最近更新 更多