这可能是一个愚蠢的问题,但我刚看到一个问题 如何为泛型类型创建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方法,并且正在使用来自的实现 Object
)。
相同的推理适用于其他(有时是有用的方法),如 toString
, hashCode
第二种方法没有提供这些方法的有用实现。
如果你包含谷歌 番石榴 你的项目中的库(你应该;它很棒),使用它 TypeToken
得到一个类型。谷歌的 GSON 库(用于与JSON交互)有类似的 版。两者都是这样使用的(得到一个 Type
代表 List<String>
:
Type t = new TypeToken<List<String>>(){}.getType();
如果您不想依赖任何第三方库,您仍然可以使用匿名类型来获取泛型 具体 用一行代码键入(这种技术不适用于接口,可能比抽象类型的值更麻烦)。得到一个 Type
代表 HashMap<String, String>
, 做这个:
Type t = new HashMap<String, String>(){}.getClass().getGenericSuperclass();
我已经证实了这一点 Type
例 .equals()
该 Type
由...创建的实例 GSON的 TypeToken
,虽然没有验证相同 番石榴的版本 TypeToken
,目前我无法访问。 (Guava是一个更通用的库,对于各种各样的东西非常方便,你应该可以使用它。)
实际上,我认为执行此操作的最简单方法(==最少代码)将是一个扩展您感兴趣的类型的虚拟接口,然后 getGenericInterfaces()[0]
从它的类(使用 getGenericSuperclass()
如果你对课程感兴趣):
private interface MapStringString extends Map<String, String> {}
private static ParameterizedType mapStringString(){
return (ParameterizedType) MapStringString.class.getGenericInterfaces()[0];
}
但是,它不能很好地扩展,因为你必须为每个人创建一个新类 ParameterizedType
你想表达。我不明白为什么你的实现不会这样做(除非在某处有缩小的演员),它确实具有吸引人的好处,你可以使它可重用。