如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。
@Component
public class A<T, S> {
private Class<T> tType;
private Class<S> sType;
@SuppressWarnings("unchecked")
public A() {
this.tType = (Class<T>) // some method to take the type
this.sType = (Class<S>) // some method to take the type
}
public T toModel(S regras) {
return modelMapper.map(regras, tType);
}
背景:
public class B{
@Autowired
private A<SomeClassX, SomeClassY> var;
// Some code
我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如:
@SuppressWarnings("unchecked")
public A() {
this.tType = (Class<T>) getGenericClassType(0);
this.sType = (Class<S>) getGenericClassType(1);
}
private Type getGenericClassType(int index) {
Type type = getClass().getGenericSuperclass();
while(!(type instanceof ParameterizedType)) {
if (type == null) {
return null;
}
if (type instanceof ParameterizedType) {
type = ((Class<?>) ((ParameterizedType) type).getRawType()).getGenericSuperclass();
} else {
type = ((Class<?>) type).getGenericSuperclass();
}
}
return ((ParameterizedType) type).getActualTypeArguments()[index];
}
或
@SuppressWarnings("unchecked")
public A() {
this.tType = (Class<T>) GenericTypeResolver.resolveTypeArguments(getClass(), GenericConverter.class)[0];
this.sType = (Class<S>) GenericTypeResolver.resolveTypeArguments(getClass(), GenericConverter.class)[1];
}
你不能。泛型是编译器想象出来的:编译器使用泛型生成错误和注入类型转换,然后将其全部删除。它不在类文件中,因此在运行时不可用,因此,“我的t实际上是什么”的概念是不可能的。
有一些变通方法:
当然,您可以将一个j.l.Class实例传递给构造函数。您的代码片段使用了“A”和“B”这两个名称,这非常不幸,因为单大写通常用于类型vars,所以我将把它们命名为mycopa和MyCombB。
像这样的东西:
public class MyCompA<S, T> {
private final Class<S> sourceType;
private final Class<T> targetType;
public MyCompA(Class<S> sourceType, Class<T> targetType) {
this.sourceType = sourceType;
this.targetType = targetType;
}
public T toModel(S regras) {
return modelMapper.map(regras, targetType);
}
}
尽管如此,听起来您实际上并不需要任何源类型,所以您最好不要使用它。
这种策略有两个问题:
int
,原语有一个表示它的j.l.Class实例;您可以使用表达式int.class获得它int是无效的泛型(至少还没有,可能在将来的java版本中):Class
一种方法是STT。它们看起来很时髦。制作它们:
TypeToken<List<String>> = new TypeToken<>() {};
注意这里奇怪的尾随符。这将创建一个匿名类,而类确实携带泛型信息,这些信息在编译后仍然存在,因此可以通过反射访问进行查询。运行时系统对它没有任何作用——就JVM而言,它是注释(JVM不知道泛型是什么,也不把它们用于任何事情。它位于类文件中,仅用于javac,但我们可以通过反射来读取它,就是这样)。
public abstract class TypeToken<T> {
public Type getType() {
Type t = getClass().getGenericSuperclass();
if (!(t instanceof ParameterizedType pt)) throw new IllegalStateException("Incorrect use of TypeToken: " + t);
Type[] typeArgs = pt.getActualTypeArguments();
if (typeArgs.length == 1) return typeArgs;
throw new IllegalStateException("Incorrect use of TypeToken: " + t);
}
我已经向您展示了如何创建这些实例。如果您愿意,您可以在构造函数中包含对
getType()
的调用(您可能想要缓存返回值;它不能更改并且反射可能有点昂贵),因为这样您将在创建无效类型标记时获得异常(例如:new TypeToken() {}
-这是原始用法,当然在这里不起作用,重点是捕获中的内容
显然,您的
ModelMapper.map
方法需要Class类型的值
问题内容: 我有一个列表,程序是这样的:。有什么方法可以使用T变量获取类的名称(因此我可以从内部知道T是否为String,Socket等)? 编辑:没关系,在这里找到了答案。 问题答案: 简短答案 :您不能。 长答案 : 由于使用Java实现泛型的方式,泛型T在运行时不会保留。您仍然可以使用私有数据成员: 用法示例:
问题内容: 我在使用泛型时遇到麻烦。给出以下示例: 什么 ???应该 ? 不工作… 也不。 不工作… 如果有Java泛型专家,我需要帮助…:/ 问题答案: 由于类型擦除,您可能无法获得除外。你将不得不使用不安全的类型转换投下的-具体而言,将做的工作。
问题内容: 背景 我曾经写过这种方法: 应该这样称呼它: 这很好用(尽管我在研究当前容易出错的问题时在这里的答案中已经看到)。 目前的情况 无论如何,现在我正在编写以下代码(在扩展javax.servlet.jsp.tagext.TagSupport的类中): 目的是可以这样称呼: 我的评估方法中的代码显然不起作用。的第二个参数应该是Class对象。这导致我: 我的问题 如何获得通用(返回)类型的
问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据
问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符
如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个