处理java泛型处理的更好方法是什么?

时间:2016-02-01 00:01:15

标签: java generics

有一个方法:

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<T>的方法。它接受输入并创建给定类的实例。因此,foo的真实签名可能是:

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

用法可能是:

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

这里没有什么不寻常之处 - 它是任何解析器和转换器的相当常见的签名。

3 个答案:

答案 0 :(得分:0)

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

您可以做的最好的事情是将您的演员阵容与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的{​​{1}}并且应该将其转换为{String的能力1}},本身就是一项非常重要的任务。

毫无疑问,您会发现编译器不知道返回的Set是否为Set。那些信息不可用。

答案 1 :(得分:-1)

由于删除了java的泛型,List<String>List<Object>都由一个类表示:List。如果你真的需要在运行时表示一个实例化的泛型类型,你可以使用Guava's TypeToken这样做,但这有很大的开销,并不总是像你想象的那样有用。

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

答案 2 :(得分:-1)

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

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

function testingCall(){
    var data = testingAjax(url);
    alert(data);
}

这很丑陋但是有效。