Java 对象返回类型与通用方法

标签 java generics

我看到了几个关于泛型返回类型的问题,但没有一个回答我的问题。
如果没有任何参数的限制,比如JayWay中的如下方法:

public static <T> T read(String json, String jsonPath, Filter... filters) {
    return new JsonReader().parse(json).read(jsonPath, filters);
}

将其用作泛型有什么意义?
我告诉我团队的人,这种方法应该用作:

JsonPath.<Boolean>read(currentRule, "$.logged")

代替:

(boolean) JsonPath.read(currentRule, "$.logged")

但我真的分不出来...

最佳答案

编译器在代码中插入不可见的强制转换来工作泛型。

例如,在将泛型添加到语言之前,您必须这样做。

List list = new ArrayList();
list.add("Foo");
list.add("Bar");
String str0 = (String) list.get(0);
String str1 = (String) list.get(1);

这很烦人。因为 get() 返回 Object,所以每次想要从 List 中获取 String 时都必须进行强制转换>.

现在,List 是通用的,get() 返回 T,所以你可以这样做。

List<String> list = new ArrayList<>();
list.add("Foo");
list.add("Bar");
String str0 = list.get(0);
String str1 = list.get(1);

这里发生的是编译器通过为您添加转换将新版本转换为旧版本,但它们仍然存在。

但是,泛型的全部意义在于这些编译器生成的强制转换保证是安全的 - 即它们不可能在运行时抛出 ClassCastException

在我看来,如果你使用泛型来隐藏保证安全的强制转换,仅仅因为它们很烦人,那就是对该功能的滥用。

它是否是一个泛型方法并且你这样做

Boolean a = JsonPath.<Boolean>read(currentRule, "$.logged");

或者它返回 Object 而你这样做

Boolean a = (Boolean) JsonPath.read(currentRule, "$.logged");

两个 版本都可能在运行时抛出 ClassCastException,所以我认为最好强制转换,这样至少你知道你正在做某事这可能会失败。

我认为泛型方法的返回类型涉及类型参数T是不好的做法,如果方法参数没有,除非返回的对象不能使用以一种损害类型安全的方式。例如,

public static <T> List<T> emptyList()

in Collections 没问题(列表为空,因此不能包含错误类型的元素)。

在你的情况下,我认为 read 方法不应该是通用的,应该只返回 Object

关于Java 对象返回类型与通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36477444/

相关文章:

java - 速度。无法加载我的资源

java - 如何获取对话框大小?

ios - 在泛型类型和协议(protocol)一致性之间快速切换

java - 在进行查询的同一页面中显示结果的简单方法 - Spring App

java - 从 JDBC 连接处理 Sybase 中的登录错误的正确方法是什么?

java - java函数声明中<T, U extends T>的含义

java - 将泛型与 GWT-RPC 一起使用未按预期工作

java - 如何在java中实现抽象和泛型?

c# - 通用工厂方法创建通用类型的来龙去脉

Swift:运行时的通用类​​型推断