【问题标题】:Why is it `<T>Type` as return type in Java Generics and not `Type<T>`?为什么 Java 泛型中的返回类型是 `<T>Type` 而不是 `Type<T>`?
【发布时间】:2013-05-07 15:15:08
【问题描述】:

我刚刚为assertThat() 写了一个简单的JUnit Matcher,当然它需要泛型

幸运的是,我为static &lt;T&gt;Matcher not(Matcher&lt;T&gt; m)...返回类型找到了正确的语法,虽然我不明白为什么

  • 返回类型它的&lt;T&gt;Matcher
  • 参数列表中是Matcher&lt;T&gt;

为什么返回类型中是&lt;T&gt;Matcher这背后的概念是什么?

我来自 C++,可以很好地处理它的 模板。我知道泛型的工作方式不同,但这就是为什么这让我感到困惑。

这是我自己的Matcher 课程。看静态助手not

import org.hamcrest.*;

/** assertThat(result, not(hasItem("Something"))); */
class NotMatcher<T> extends BaseMatcher<T> {
    /** construction helper factory */
    static <T>Matcher not(Matcher<T> m) {  //< '<T>Matcher' ???
        return new NotMatcher<T>(m);
    }
    /** constructor */
    NotMatcher(Matcher<T> m) { /* ... */  }
    /* ... more methods ... */
}

【问题讨论】:

标签: java generics return-type hamcrest


【解决方案1】:

我希望这个插图对您有所帮助。

上图是对问题标题的直接回应:为什么Java泛型中的返回类型是&lt;T&gt;Type而不是Type&lt;T&gt;

在 Towi 的示例中还有其他几点需要考虑,请参阅评论跟踪。

【讨论】:

  • 很酷的答案 ^^ 但是,应该提到(a)方法声明的类型参数 T 隐藏了类的类型参数 T 和(b)在这种情况下返回类型 Matcher 是原始类型。
  • @MichaelSchmeißer 谢谢,我会在我的回答中添加一个注释,并使用您的评论作为补充。我的回答是对标题的直接回应:为什么在 Java 泛型中将 &lt;T&gt;Type 作为返回类型而不是 Type&lt;T&gt;
  • 嗯,实际上,由于方法是静态的,我必须撤销 (a) - 在这种情况下,T 不会相互隐藏。
  • @MichaelSchmeißer “隐藏 T”,当然。我应该写static &lt;U&gt; Matcher not(Matcher&lt;U&gt; m)。还是static &lt;U&gt; Matcher not(Matcher&lt;T&gt; m)?什么是“原始类型”?
  • @Ronixus Gotya。 Matcher 是返回类型,&lt;T&gt; 是泛型声明。但是为什么返回类型不依赖于泛型参数呢? Matcher 得到一个类型参数 &lt;T&gt;,所以我会假设返回值,如果它是 Matcher 也取决于它。我想我可以声明static &lt;U,V&gt; Matcher not(Matcher&lt;U&gt; u, Matcher&lt;V&gt; v)?我要返回什么样的Matcher?也许是新的Matcher&lt;Z&gt; 或其他Matcher&lt;U&gt;Matcher&lt;V&gt;...
【解决方案2】:

你真的想要

static <T> Matcher<T>

您需要第一个“T”来声明泛型方法的类型。第二个“T”是 Matcher 类的类型参数。

【讨论】:

  • 哦!那很好。那为什么我的程序可以运行呢?那我在这里返回什么样的匹配器呢?是 Java 自己推断的吗?
  • 您正在返回一个“原始类型”,这是允许的,但不鼓励这样做。你失去了所有的类型安全。这就像使用List 而不是List&lt;String&gt;。该类中使用该类型的任何泛型方法将只是 Object 而不是 T
  • “该类中使用该类型的任何泛型方法都将只是 Object 而不是 T” ...这意味着可以应用完全不同的重载。这是not-Method 现在有一个不正确的返回类型,它被传递给assertThat()——它有几个重载,其中一个也在Object 上(我假设)。但是因为随后调用了equals(),所以它又可以工作了。幸运的我。对吗?
  • @towi,基本上,是的,你很幸运;)
猜你喜欢
  • 2016-10-24
  • 1970-01-01
  • 2021-06-28
  • 2023-01-19
  • 2011-10-03
  • 2021-02-06
  • 2016-07-22
  • 2022-10-07
相关资源
最近更新 更多