【问题标题】:Please help to read this abstract datatype within Java code [duplicate]请帮助在 Java 代码中阅读此抽象数据类型 [重复]
【发布时间】:2019-09-03 10:38:39
【问题描述】:

我正在尝试从 Spring API 项目中了解以下 Java 方法。

此方法用于在另一台服务器上获取 HTTP GET 响应。

根据我对抽象数据类型的理解,我认为我们提供的响应数据类型为ResponseEntity<T>足以解释方法的返回值。

为什么我们在这个方法的返回类型之前需要<T>

public <T> ResponseEntity<T> getWithJson(String url, @Nullable String json, Class<T> type) {

【问题讨论】:

  • 为了将来参考,在您的问题中包含文本图片通常不是一个好主意,除非有充分的理由 - 99.999% 的情况下您最好将实际文本粘贴到而是提问。
  • @JonK 你不觉得一张图片真的有助于解释问题吗,它可以帮助读者快速理解意思。
  • 你需要一个关于 Java 泛型的教程。
  • 这很有帮助。您必须仔细研究Java 中“泛型”的整个 概念。含义:知道两个法语单词不足以理解法语的完整句子。您应该退后一步,花几个小时阅读有关 java 泛型的内容。这在 Java 中是一件的事情,学习所有细节需要时间。但是了解所有细节非常有帮助,因为如前所述:泛型在 java 中很重要。
  • &lt;T&gt;是在关键字public之后还是在关键字static之后都无所谓,还是同一个概念:带有类型参数的泛型方法。

标签: java


【解决方案1】:

&lt;T&gt; 用于表示/标识您将在函数中使用的Generic 类型的名称。例如,您可以使用不同的名称,例如&lt;Test&gt;,但是无论您在哪里使用通用类标识符,都必须使用类名 Test。

如果在方法的返回类型之前没有写泛型类型名称,Java 不会将该方法视为泛型函数。相反,它将&lt;T&gt; 视为一个实际的类,并将在类路径中查找该类。

现在,当您使用此功能时。 Java 将替换为您要使用的 Object 类型。

ResponseEntity<String> hello() {
    return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}

这里的&lt;String&gt;关键字表示&lt;T&gt;需要被视为String类型,函数返回String类型的对象。

【讨论】:

  • @Nabeel Mehmood 感谢您的回复。除了提到 Jave Generic,我想问的是:关键是我们已经在 ResponseEntity 之后有 T,即 ResponseEntity 逻辑上,那么为什么我们需要 T 在它前面呢?我认为如果没有 在那个地方前面,我们仍然有足够的逻辑来推断,我们希望将通用 DataType 传递给 ResponseEntity,对吧?
  • &lt;T&gt; 本身并没有任何意义。正如我在回答中提到的,如果您在返回数据类型之前不写任何内容,&lt;T&gt; 将不会被视为泛型。相反,它将被视为一个类本身。 Java 将在您的程序中查找名为&lt;T&gt; 的类,然后构建失败。数据类型之前的 &lt;T&gt; 几乎是代码的一部分,它告诉 Java 这是一个泛型函数,并且方法中存在的任何 &lt;T&gt; 本身都不是具体的类。
  • public ResponseEntity&lt;T&gt; foo()public ResponseEntity&lt;String&gt; foo() 没有什么不同。它是返回类型之前的标识符,使它成为一个泛型函数。
  • @Nabeel Mehmood 感谢您的回复。我今天学到了一些新东西。
【解决方案2】:

您正在查看 Java 泛型 - 背景阅读:

在这种情况下,去看看ResponseEntity的来源。在这种情况下,您会看到类/接口本身是“通用的”——根据实例化的方式,它的行为会有所不同。

经典的例子是一个简单的List

import java.util.ArrayList;
import java.util.List;

class Scratch   {
    public static void main(String[] args) {
        List<String> strings = new ArrayList<>();
        List<Integer> integers = new ArrayList<>();

        // some small details
        strings.add("a string");
        integers.add(Integer.valueOf(6));

        String s = strings.get(0);
        Integer i = integers.get(0);

        System.out.println("s: " + s);
        System.out.println("i: " + i);

    }
}

输出:

s: a string
i: 6

看看如何无需在任何地方投射(String)(Integer)&lt;T&gt; 类型现在是编译时测试而不是运行时测试,因此可以消除整个错误类别,只是为了让您的代码编译

【讨论】:

  • @Geoff Williams:提供的示例与我的问题不太匹配,它只是一个与通用数据类型相关的简单案例。
猜你喜欢
  • 2021-12-01
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-17
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多