Java 返回类实例及其泛型类型
下面是一个简单的示例,演示了我遇到的与类型擦除相关的问题。我有一门课是这样的:Java 返回类实例及其泛型类型,java,generics,type-erasure,generic-type-argument,Java,Generics,Type Erasure,Generic Type Argument,下面是一个简单的示例,演示了我遇到的与类型擦除相关的问题。我有一门课是这样的: public abstract class AbstractHandler<T> { ... public abstract Class<T> handledType(); } public class ThingListMap { private Map<String, List<Thing>> thingListMap; ...
public abstract class AbstractHandler<T> {
...
public abstract Class<T> handledType();
}
public class ThingListMap {
private Map<String, List<Thing>> thingListMap;
...
}
我只是使用ThingListMap
作为泛型类型参数
另一种可能的解决方法是执行强制强制强制转换:
public Class<Map<String, List<Thing>>> handledType() {
return (Class<Map<String, List<Thing>>>) new HashMap<String, List<Thing>>().getClass();
}
公共类handledType(){
返回(类)新HashMap().getClass();
}
有没有更优雅的方法
EDIT:作为对其中一个答案的响应,我无法更改
handledType
方法的签名,因为我不拥有或控制其源代码。由于某些原因,Java不允许您将Map.class
直接转换为class
。这是一个未经检查的演员阵容
但投两次是合法的,先投给类
,然后投给类
return(Class)(Class)Map.Class;
作为未选中的强制转换,您可能需要添加
@SuppressWarnings(“未选中”)
番石榴的方法是使用s。你的班级将成为
public abstract class AbstractHandler<T> {
public TypeToken<T> handledType();
}
public class ConcreteHandler extends AbstractHandler<Map<String, List<Thing>>> {
@Override
public TypeToken<Map<String, List<Thing>>> handledType() {
return new TypeToken<Map<String, List<Thing>>>() {};
}
}
公共抽象类AbstractHandler{
公共类型令牌handledType();
}
公共类ConcreteHandler扩展了AbstractHandler{
@凌驾
公共类型令牌handledType(){
返回新的TypeToken(){};
}
}
需要更多关于该方法的用途的信息有什么方法可以做到这一点吗?“在普通Java中,没有。@eduyayo这更多的是一个概念性的问题。我有一个解决方法,但我想看看是否有一个更优雅的方法。您的类没有得到很好的构思。classJava.lang.class
的实例代表类(duh),但您试图用一个来表示一个类型,这是一个更一般的概念。Java确实有一个类型
类来表示这个概念,但它可能也不能满足您的目的。@JohnBollinger我完全同意,但我没有设计这个类,所以我无法更改它。:(是的,那将是理想的。不幸的是,我无法更改AbstractHandler
中handledType
的签名。我将在问题中提到这一点。@eduyayo我不理解您的评论或它如何适用于此答案。”出于某种原因[…]“基本上,这与不能将列表
强制转换为列表
的原因相同。两者都不是另一个的超类型或子类型。另请参见。RE:这里的答案是,强制转换对于对象创建之类的事情很好,但请注意,在这种情况下,例如类
将=
a类
。这是一个更好的选择(我想是主观的:p)我强制转换一个特别的HashMap
实例类的变体。我喜欢这样一个事实,即我不必创建那个特别的实例。@Radiodef是的,这就是原因。感谢您指出这一点。@VivinValiath同样,这更接近真实类型,因为您返回的是HashMap.class
而不是Map.class
。
return (Class<Map<String, List<Thing>>>) (Class<?>) Map.class;
public abstract class AbstractHandler<T> {
public TypeToken<T> handledType();
}
public class ConcreteHandler extends AbstractHandler<Map<String, List<Thing>>> {
@Override
public TypeToken<Map<String, List<Thing>>> handledType() {
return new TypeToken<Map<String, List<Thing>>>() {};
}
}