繁体   English   中英

使用匿名类创建参数化类型对象

[英]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的实现)。

同样的推理适用于其他(有时有用的方法),例如toStringhashCode等。第二种方法不提供这些的有用实现。

如果您的项目中包含 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()是由GsonTypeToken创建的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创建一个新类。 我不明白为什么你的实现不会做(除非在某处有缩小强制转换),而且它确实有一个吸引人的好处,你可以使它可重用。

除了上面提到的来自 Google 的库之外,还有一个来自 Apache 的库可以完成这项工作。

import org.apache.commons.lang3.reflect.TypeUtils;
...
ParameterizedType type = TypeUtils.parameterize(List.class, Double.class);
...

在GitHub上FINDE代码在这里和Maven的文物在这里

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM