我正试图为一个使用泛型类型参数进行参数化的类施展一些Guava TypeToken
魔法,但是当我试图通过< code > class . forname(String)方法实例化它时,却得到一个< code > ClassNotFoundException 。
public class EnumeratedMenu<E extends Enum<E>,T extends EnumeratedBean<E>> {
private final TypeToken<EnumeratedMenu<E,T>> typeToken =
new TypeToken<EnumeratedMenu<E,T>>(getClass()) { };
private Class<T> getBean() {
TypeToken<?> genericBeanParam = typeToken.resolveType(EnumeratedMenu.class.getTypeParameters()[1]);
try {
//This generates a ClassNotFoundException because of the generic type parameter that EnumeratedBean has.
return (Class<T>)Class.forName(genericBeanParam.getType().getTypeName());
} catch(ClassNotFoundException e) {
log.error("Unable to find the class definition for {}", genericBeanParam.getType().getTypeName());
log.catching(e);
}
}
}
我得到这个例外:
"无法找到EnumatedBean的类定义
ContextMenuOption$ContextType
是 EnumeratedBean
的泛型 enum
参数的运行时类型。如何获取所需的类对象?
澄清:
我需要构造一个类的实例,以便与一个生成器对象一起使用,该对象将构造一个菜单选项,如下所示:
T optionBean = beanFactory.create(beanClass);
IEnumeratedMenuOptionBuilder<E,T> builder = new EnumeratedMenuOptionBuilder<>(optionBean);
builder.setDriver(getDriver()).setTimeoutInSeconds(getTimeoutInSeconds())
.setEnumerationFunction(getEnumerationFunction());
匿名用户
这是不可能的,因为不管参数化如何,总是只有一个<code>类。这就是Java泛型处理类型擦除的方式。有关如何和为什么的详细解释,您可能需要阅读:
http://www . angeli kalanger . com/generics FAQ/FAQ sections/technical details . html
但是对于实例化,你只需要使用你已经拥有的类
;并按所需方式强制转换泛型类型签名。
例如,这意味着您可以实际执行以下操作:
List<String> strings = new ArrayList<String>();
List<Integer> numbers = (List<Integer>)(List<?>) strings;
numbers.add(Integer.valueOf(12));
没有运行时异常。没有真正的运行时信息限制内容;只有隐式铸造。但是,如果您尝试以下操作,将会得到运行时异常:
String str = strings.get(0);
因为尽管底层<code>列表
因此,实例化的工作方式可能如下:
List<String> s = (List<String>) ArrayList.class.newInstance();
但是使用任何你想要的泛型类型。
编辑:
如果需要Guava的< code>TypeToken,它的javadocs建议您要么使用< code>getRawType()获取原始类,要么使用< code>constructor()直接创建实例。
你到底想在这里做什么?
你永远也上不了课
可能有其他方法可以实现您想要的结果,但不清楚您当前想要的结果是什么。例如,您想使用要返回的
Class
来做什么?也许可以在没有中间Class
对象的情况下做到这一点。
编辑:
由于看起来你想要的是能够创建
一个T
的实例,所以这里有一个如何使用TypeToken
做到这一点的示例:
public class EnumeratedMenu<E extends Enum<E>, T extends EnumeratedBean<E>> {
// Just get the type of T, that's what we care about here
private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};
private T create() {
try {
// Using the raw type Class object for the token to
// get at its default constructor.
return typeToken.constructor(typeToken.getRawType().getConstructor())
.invoke(null);
} catch (Exception e) {
// ...
}
}
}
问题内容: 是否可以使用Java反射从另一个类实例化私有内部类。例如,如果我采用了这段代码 是否可以实例化并从main类中的main方法获得对Test的访问。 问题答案: 使用反射时,您会发现该内部类的构造函数将外部类的实例作为附加参数(总是第一个)。 例:
是否可以从类main中的main方法实例化并获得对Test的访问。
问题内容: 如何使用反射在Java中创建通用的参数化类? 我有 我需要一个实例。 我尝试了 但找不到可以让我获取适当类型的实例的语法,例如说 那么,我该怎么做呢? 问题答案: Java使用基于擦除的仿制药(即,类型参数是在运行时,例如擦除,并且被视为在运行时是同一类型)。由于反射本质上是运行时功能,因此根本不使用或不涉及类型参数。 换句话说,当您使用反射时,您只能实例化原始类型(,不能实例化)
我尝试实例化以下Java代码中定义的内部类: 我得到了这个例外: 我错过了什么?
我不能创建B-Object,但为什么呢? 例外情况是:
问题内容: 我正在使用reflect.MakeFunc编写函数。该函数可以返回错误。成功时,我希望它为错误类型的返回值返回nil。我该如何使用反射?目前我有这个: 我懂了。我也尝试添加一个之后,但我得到了。我尝试了,但出现了细分错误。 如何获得代表nil错误的reflect.Value? 问题答案: 使用以下内容: 让我们分解一下。第一步是为: 。更简单的方法不起作用,因为参数的具体值为。没有类型