【问题标题】:Better way to deal with java generics handling?处理java泛型处理的更好方法?
【发布时间】:2016-02-01 00:01:15
【问题描述】:

有一个方法:

public <T> T foo(Class<T> type);

当我这样称呼它时:

String s = foo(String.class);

一切都很好。这也有效:

Set s = foo(Set.class);

但是,以下内容无法编译:

Set<String> s = foo(Set.class);    // compilation error

所以我用一些愚蠢的东西来修复它:

Set<?> tmp = foo(Set.class);
Set<String> s = (Set<String>) tmp;

我无法更改foo() 的签名。有没有更好的方法来完成我错过的这项任务?

编辑

出于某种奇怪的原因,我不清楚我在这里做什么。所以,foo 方法是一个需要一些输入加上Class&lt;T&gt; 的方法。它接受输入并创建给定类的实例。所以,foo 的真正签名可能是:

public <T> T parseStringToClass(String input, Class<T> targetClass);

而用法可能是:

Integer value = parseStringToClass("123", Integer.class);

这里没有什么不寻常的地方——对于任何解析器和转换器来说,它都是相当常见的签名。

【问题讨论】:

  • 这在 Java 8 中并不是什么新鲜事,答案或多或少是“不,没有;擦除不能按您希望的方式工作。”
  • @LouisWasserman 也许你能解释一下?这不就是 SO 的目的吗?
  • @игор 在 Java 8 中你的代码 Set s = foo(Set.class);带有警告,但已编译。

标签: java generics


【解决方案1】:

如果您正在寻找编译器,您将不会得到任何帮助。正如在 cmets 中观察到的那样,泛型不会按照您希望的方式工作。

你能做的最好的就是结合你的演员表和你对foo()的调用:

@SuppressWarnings("unchecked") // Added to keep my Eclipse happy
Set<String> s = (Set<String>) parseStringToClass("Set<String>, Hello World, Goodnight Irene", Set.class);

这当然依赖于parseStringToClass 的能力来识别它正在被传递一个String,其中包含多个Strings,并且它们应该被转换为Set,这本身就是一项不平凡的任务.

毫无疑问,您会发现编译器不知道返回的Set 是否是Set&lt;String&gt;。该信息不可用。

【讨论】:

  • 如果反对者愿意发表评论,那么投诉的具体内容是什么?
【解决方案2】:

由于 java 的泛型被删除,List&lt;String&gt;List&lt;Object&gt; 都由一个类表示:List。如果您确实需要在运行时表示一个实例化的泛型类型,您可以使用Guava's TypeToken 来执行此操作,但这会产生相当多的开销,而且并不总是像您想象的那么有用。

最终取决于foo 方法如何以最优雅的方式解决这个问题。

【讨论】:

    【解决方案3】:

    根据下面的链接,您无法获取泛型类型的文字 http://goo.gl/6CtqGt

    如果你真的需要使用一种方法,我建议你做的是:

    Set<String> set = foo(new HashSet<String>().getClass());
    

    虽然很丑,但是很管用。

    【讨论】:

    • PS.:我在手机上,稍后我会编辑我的答案并改进它。
    • Eclipse 对此抱怨。它说,“类型安全:类型 capture#1-of ? extends HashSet 的表达式需要未经检查的转换以符合 Set”。这是因为类文字没有携带编译器强制类型安全所需的所有信息。
    • 即使编译成功,创建新的HashSet 只是为了满足编译器有点过分:)
    • @erick-g-hagstrom 您使用的是哪个 java 版本?在这里它适用于 java 8。
    猜你喜欢
    • 2010-09-25
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2012-10-28
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多