[英]Creating parameterized type object using anonymous class
这可能是一个愚蠢的问题,但我刚刚看到一个问题,询问如何为泛型 type 创建一个 Type 变量。 共识似乎是你应该有一个返回该类型的虚拟方法,然后使用反射来获取它(在这种情况下他想要Map<String, String>
)。 像这样的事情:
public Map<String, String> dummy() { throw new Error(); }
Type mapStringString = Class.forName("ThisClass").getMethod("dummy").getGenericReturnType();
我的问题是,没有那么多使用反射,你不能做这样的事情:
Type mapStringString = new ParameterizedType() {
public Type getRawType() {
return Map.class;
}
public Type getOwnerType() {
return null;
}
public Type[] getActualTypeArguments() {
return new Type[] { String.class, String.class };
}
};
这行得通吗? 如果没有,为什么不呢? 如果确实如此,会有哪些危险/问题(除了能够返回某些类型,如Integer<String>
这显然是不可能的。
当然可以,而且对于大多数应用程序来说,这可能就足够了。
但是,使用第一种方法,您可以获得更精致的对象。 例如,假设您使用第一种方法创建对象type1
,使用第二种方法创建对象type2
。 然后type1.equals(type2)
将返回 true(因为第一个方法返回一个正确实现 equals 方法的对象)但type2.equals(type1)
将返回 false(因为在第二个方法中,您没有覆盖 equals -method,并且正在使用Object
的实现)。
同样的推理适用于其他(有时有用的方法),例如toString
、 hashCode
等。第二种方法不提供这些的有用实现。
如果您的项目中包含 Google 的Guava库(您应该这样做;它很棒),请使用它的TypeToken
来获取类型。 Google 的Gson库(用于与 JSON 交互)有一个类似的版本。 两者都像这样使用(获取表示List<String>
的Type
:
Type t = new TypeToken<List<String>>(){}.getType();
如果您不想依赖任何第三方库,您仍然可以使用匿名类型通过一行代码获得通用的具体类型(这种技术不适用于接口,并且可能比 Abstract 的价值更麻烦类型)。 要获取表示HashMap<String, String>
的Type
,请执行以下操作:
Type t = new HashMap<String, String>(){}.getClass().getGenericSuperclass();
我已经验证生成的Type
实例.equals()
是由Gson的TypeToken
创建的Type
实例,但尚未验证Guava版本的TypeToken
,我目前无法访问。 (Guava 是一个更通用的库,它对各种事情都非常方便,无论如何你都应该使用它。)
实际上,我认为最简单的方法(==最少代码)是一个扩展您感兴趣的类型的虚拟接口,然后从它的类中获取getGenericInterfaces()[0]
getGenericSuperclass()
如果您感兴趣,请使用getGenericSuperclass()
一类):
private interface MapStringString extends Map<String, String> {}
private static ParameterizedType mapStringString(){
return (ParameterizedType) MapStringString.class.getGenericInterfaces()[0];
}
但是,它不能很好地扩展,因为您必须为要表示的每个ParameterizedType
创建一个新类。 我不明白为什么你的实现不会做(除非在某处有缩小强制转换),而且它确实有一个吸引人的好处,你可以使它可重用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.