当前位置: 首页 > 知识库问答 >
问题:

在Java中为泛型方法传递类型参数为类型参数的类

方绪
2023-03-14

问题总结:我想传递一个带有类型参数(如ArrayList)的类

假设我有一个方法:

    public static <T> T getGenericObjectFromJson(String json, Class<T> genericType){
        // details unimportant, basically returns an object of specified type
        return JsonParser.fromJson(json, genericType); 
    }

当然,这个方法对于任何类型的类都能很好地工作。我可以这样称呼这个方法,例如:

getGenericObjectFromJson(jsonString, User.class)

问题是:我发现我不能这样做:

getGenericObjectFromJson(jsonString, ArrayList<User>.class)

从语法上来说,这显然是无效的。然而,我甚至不确定我将如何完成这样的事情。当然,我可以通过ArrayList。类,但是泛型类型的添加使它在语法上不再有效,我想不出解决方法。

唯一直接的解决办法是这样的(这似乎有点愚蠢):

getGenericObjectFromJson(jsonString, new ArrayList<User>().getClass())

然而,不管怎样,我们最终还是会丢失泛型类型,只会得到一个未知类型的ArrayList(尽管它可以强制转换)。另外,不必要地实例化一个对象。

到目前为止,我唯一的解决方案是将该方法包装在一个类中,该类包含一个可以实例化的泛型类型参数,如下所示:

public class JsonDeserializer<T>...

在这种情况下,getGenericObjectFromJson方法将使用类的泛型类型。

问题:归根结底,我很好奇为什么我不能传递一个带有类型参数的类,以及是否有办法完成我试图做的事情。

和往常一样,如果这个问题有任何问题,请告诉我。


共有1个答案

王才
2023-03-14

这在Java中实际上是可能的,使用一些“技巧”。不要屈服于C#狂热分子的压力!(j/k)

诀窍是创建一个扩展泛型类型的类,并通过. getGenericSuperclass(). getGenericInterface()返回的Type访问父类的类型参数的值。

这是相当繁琐的,为了简化我们的生活,谷歌已经为我们编写了代码中大部分无聊的部分,并通过Guava使其可用。

检查TypeToken类,它完全符合您的要求。例如:

TypeToken<List<String>> stringListTok = new TypeToken<List<String>>() {};

然后你传递一个TypeToken

这在内部只是调用。getClass()。getGenericSuperclass()(或…Interfaces()),然后将一些丑陋的类型转换为ParameterizedType,并从中检索所有信息(.getActualTypeArguments(),等等)。

最后,如果您想对依赖项注入做类似的事情(例如,假设您需要注入一个类)

 类似资料:
  • 问题内容: 问题摘要: 我想将具有类型参数(例如)的类作为类型参数传递给泛型方法。 假设我有一个方法: 当然,此方法对于任何类型的类都可以正常使用。我可以这样调用该方法,例如: 问题: 我发现我不能这样做: 从句法上讲,这显然是无效的。但是,我不确定如何实现这样的目标。我当然可以通过,但是泛型类型的添加使其在语法上不再有效,并且我想不出解决方法。 唯一的直接解决方案是这样的事情(看起来很愚蠢):

  • 问题内容: 您认为可以创建类似的东西吗? 问题答案: 是的你可以。 用法示例:

  • 我写了以下方法 我如何将不同的枚举类型传递给第二个参数?我知道我不能创建枚举的实例,但初始化枚举意味着我将传递一个值,而不是整个初始化的枚举,如下所示...其他枚举也将传递给相同的方法以实现组合细节

  • 问题内容: 我有一个方法以a 作为参数。 在中,我如何知道a 是还是a 是? 问题答案: 根据用户omain的回答“如果使用<?>,则意味着您将不会在任何地方使用参数化类型。要么转到特定类型(在您的情况下,似乎是),要么转到非常通用的“ 另外,我相信如果您使用问号,编译器将在运行时(类型;有效Java的第119页)消除类型不匹配的情况,绕过擦除,并有效地消除了使用泛型类型所带来的好处? 要回答发问

  • 问题内容: 我是从Joshua Bloch的google I / O困惑者演讲中得到的。这是代码 这个main方法会引发异常,因为它是原始类型,因此in中的所有泛型都将被删除,因此最终调用而不是。 我的问题是,即使我打电话是不是应该把它调用的方法,因为由于类型擦除,这种方法是有效的并且是类型的不是? 问题答案: 被调用的方法是在编译时定义的,而不是在运行时定义的。 如果在构造函数调用中添加参数,则

  • 我想使用泛型类作为另一个泛型类的类型参数。 起初,我对类的定义是这样的: 然后我的需求发生了变化,我不得不为我的R类型使用包装器/持有者类 到目前为止,我的尝试:(给出编译时错误: