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

Nat*_*ati 19 java generics

我看到了几个关于泛型返回类型的问题,但没有人回答我的问题.
如果没有绑定任何参数,例如JayWay中的以下方法:

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

使用它作为通用有什么意义?
我告诉我的团队成员,这个方法应该用作:

JsonPath.<Boolean>read(currentRule, "$.logged")
Run Code Online (Sandbox Code Playgroud)

代替:

(boolean) JsonPath.read(currentRule, "$.logged")
Run Code Online (Sandbox Code Playgroud)

但我真的无法区分......

Pau*_*ton 8

泛型工作由编译器将不可见的强制转换插入到代码中.

例如,在将泛型添加到语言之前,您必须执行此操作.

List list = new ArrayList();
list.add("Foo");
list.add("Bar");
String str0 = (String) list.get(0);
String str1 = (String) list.get(1);
Run Code Online (Sandbox Code Playgroud)

这非常烦人.因为get()回来Object,你有你希望得到一个每一次投StringList.

如今,它List是通用的,并且get()返回T,所以你可以这样做.

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

这里发生的是编译器通过为你添加演员阵容将新版本变成旧版本,但它们仍然存在.

但是,泛型的整个要点是这些编译器生成的强制转换保证是安全的 - 即它们不可能ClassCastException在运行时抛出.

在我看来,如果你使用泛型来隐藏那些不能保证安全的演员表,只是因为它们很烦人,那就是滥用这个功能.

它是否是一种通用方法,而且你做到了

Boolean a = JsonPath.<Boolean>read(currentRule, "$.logged");
Run Code Online (Sandbox Code Playgroud)

或它返回Object,你做

Boolean a = (Boolean) JsonPath.read(currentRule, "$.logged");
Run Code Online (Sandbox Code Playgroud)

两个版本都可以ClassCastException在运行时抛出一个,所以我认为如果你被迫投射以便至少你意识到你正在做一些可能失败的事情会更好.

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

public static <T> List<T> emptyList()
Run Code Online (Sandbox Code Playgroud)

in Collections是好的(列表为空,因此它不能包含错误类型的元素).

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


And*_*ner 5

我远离的主要原因

JsonPath.<Boolean>read(currentRule, "$.logged")
Run Code Online (Sandbox Code Playgroud)

是内部执行未经检查的演员表,并隐藏这一事实.例如,您可以在同一个地方调用此方法:

JsonPath.<String>read(currentRule, "$.logged")
Run Code Online (Sandbox Code Playgroud)

并且你无法知道那里可能存在问题,直到它在运行时实际发生 - 它仍然编译,你甚至没有得到警告.

没有离开那些不受约束的演员 - 我只是在代码中把它放在我面前,所以我知道存在潜在的危险; 这使我可以采取合理的措施来缓解这个问题.

@SuppressWarnings("unchecked")  // I know something might go wrong here!
boolean value = (boolean) JsonPath.read(currentRule, "$.logged")
Run Code Online (Sandbox Code Playgroud)