ParameterizedType.getRawType() 返回 j.l.r.Type,而不是 Class<?>?


ParameterizedType parameterized =
    (ParameterizedType) List.class.getMethod("iterator").getGenericReturnType();
Type raw = parameterized.getRawType();

ParameterizedType#getRawType()返回Type,而不是Class<?>(尽管我得到java.lang.Class现在实现Type)。为什么getRawType()不声明它的返回类型为Class<?>有一个很好的理由?是否存在getRawType()的结果可能不是Class<?>的极端情况?

对于j.l.r.Type来说,这已经足够了;这似乎是一个例子,他们可以挽救我们一个沮丧。

必须返回Class对象,没有其他方法

为什么?谁知道呢,也许是一些理想主义的偏见。如果它返回Class,这将是Class在新的Type接口中的唯一出现。

真正的问题是ClassType的混合。以前,所有类型都在Class中表示。虽然已经很乱了,但还是可以忍受的。没有很多类型。

对于新的泛型类型,他们应该设计一个独立于Class的更清晰和符合规范的Type层次结构。相反,他们把ClassType合并在一起,制造了更多的混乱。整个等级制度都说不通。任何不熟悉这门学科、不了解历史的人都会对这种无稽之谈感到震惊。

我不会对Type的设计有很高的要求。例如,ParameterizedType定义了equals(),但没有定义hashCode()。没有办法让ParameterizedType的两个实现在一个哈希映射中工作。通配符也是一种类型?没有地狱。

方法的名字getRawType()简直太蠢了。这与raw type无关。它应该被简单地命名为getClassOrInterface()。会不会太啰嗦?看看getActualTypeArguments()吧。(是的,它返回实际的参数!不是假的!)

我一直在想这件事,我有一种预感。也许他们想为未来的疯狂留下可能:

public class Z<L extends List<?>> {
    L<Double> test;
}

这不是合法的Java代码,但我认为它的意思很清楚;new Z<ArrayList<?>>().test的类型为ArrayList<Double>

如果这是合法的,((ParameterizedType) test.getGenericType()).getRawType()将返回一个TypeVariable .

Sun对ParameterizedType的实现定义了getRawType()方法来返回Class<?>。显然它只返回Class<?>

然而,在我的类路径中有更多的ParameterizedType实现——从hibernate-validator,从aspectj, hibernate-annotations, jaxb。有些返回Class<?>,有些返回Type。我不知道怎么用

除了反射api之外,Type接口层次结构还有其他用途。例如,代码生成库可以定义自定义实现。JDK 8本身有三种不同的WildcardType实现。如果ParameterizedType.getRawType()返回一个Class实例,那么您需要能够随时创建一个Class实例。

Class是一种在jvm中非常根深蒂固的类型,它具有回本机管理内存的绑定。要创建Class实例,必须拥有定义类的字节码。但是在代码生成库的情况下,字节码甚至还不存在。如果他们要求ParameterizedType返回一个Class,它将限制Type接口层次结构的适用性,使其仅适用于反射api。

这看起来可能没什么大不了的,但cast也不是什么大事。

ParameterizedType. getownertype()返回一个Type,因为它本身可能是一个Class或另一个ParameterizedType。理论上它可以返回一个TypeVariable,因为下面是有效的Java:

<M extends Map<?,?>> M.Entry<?,?> first(M map) { ... }
然而,它被编译为对类型变量擦除的静态引用,在这种情况下,M.Entry将被编译为Map.Entry。至少根据我的测试,从反射api调用getOwnerType()将是一个Class,而不是TypeVariable。

相关内容

  • 没有找到相关文章

最新更新