如何使用类标记保留嵌套泛型的泛型类型

编程入门 行业动态 更新时间:2024-10-27 12:34:51
本文介绍了如何使用类标记保留嵌套泛型的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

Java中解决类型擦除的标准方法是将类令牌传递到构造函数中.例如,我们可以定义一个通用属性类,如下所示:

The standard way in Java to work around type erasure is to pass a class token into the constructor. For example we could define a generic property class like this:

class Prop<T> { public Prop(Class<T> type) { this.type = type; } Class<T> type; T t; } class IntProp extends Prop<Integer> { public IntProp() { super(Integer.class); } }

但是如果我现在想使用另一个泛型类型参数(例如列表)并保留其泛型类型该怎么办.我本想这样做的:

But what if I now want to use another generic type argument, such as a list and also keep its generics type. I would have liked to do this:

class ListProp<J> extends Prop<ArrayList<J>> { Class<J> subtype; public ListProp(Class<J> type) { super(ArrayList<J>.class); subtype = type; } } class IntListProp extends ListProp<Integer> { public IntListProp() { super(Integer.class); } }

但是super(ArrayList<J>.class)当然不会编译,super(ArrayList.class)也不会编译.解决此问题的最佳方法是什么?

But of course super(ArrayList<J>.class) does not compile, neither does super(ArrayList.class) . What's the best way to solve this?

推荐答案

您需要使ListProp类编译的通用功夫是这一行:

The generics kung fu you need to make your ListProp class compile is this line:

super((Class<List<T>>)(Class<?>)List.class); // compiles

尝试直接从List.class投射到Class<List<T>>:

super((Class<List<T>>)List.class); //compile error

导致编译错误:

不可转换的类型;无法将'java.lang.Class'强制转换为'java.lang.Class>

Inconvertible types; cannot cast 'java.lang.Class' to 'java.lang.Class>

但是,如果您首先强制转换为类型类Class<?>,尽管类型未知,您可以然后将其强制转换为所需的类型类.

But if you first cast to typed class Class<?>, albeit an unknown type, you can then cast it the desired typed class.

然后是完全可编译的ListProp类.

The full compilable ListProp class is then.

class ListProp<T> extends Prop<List<T>> { Class<T> subtype; public ListProp(Class<T> type) { super((Class<List<T>>)(Class<?>)List.class); // magic double cast subtype = type; } }

在需要特殊代码来创建/返回列表的情况下,您可能会考虑的其他事情是Prop上t的类型化吸气剂:

Something else you may consider, in case you need special code for creating/returning a list, is a typed getter for t on Prop:

public T getT() { return t; }

然后您可以在ListProp中协变地覆盖它,以返回List<T>

which you can then covariantly override in ListProp to return a List<T>

@Override public List<T> getT() { return Arrays.asList(subtype.newInstance()); // or whatever }

应该注意的是,只有在实现使用类的情况下才需要类令牌,示例代码中未显示该类令牌.如果您实际上并未使用类标记,则可以让类型推断为您进行键入.

It should be noted that you only need the class token if your implementation uses the class, which is not shown in your example code. If you don't actually use the class token, you can let type inference do the typing for you.

更多推荐

如何使用类标记保留嵌套泛型的泛型类型

本文发布于:2023-11-16 17:26:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1606343.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:嵌套   如何使用   标记   类型

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!