应如何实现类型类型层次结构类型?
将泛型添加到 1.5 时,添加了一个具有各种子类型的接口来表示类型。 经过改装以针对 1.5 之前的版本实施。 子类型可用于 1.5 中的新泛型类型。java.lang.reflect
Type
Class
Type
Type
这一切都很好,很好。有点尴尬,因为必须下定决心才能做任何有用的事情,但可以通过试验,错误,摆弄和(自动)测试来做。除了在实施方面...Type
应该如何实施,如何实施。子类型的 API 描述说:equals
hashCode
ParameterizedType
Type
实现此接口的类的实例必须实现一个 equals() 方法,该方法等于共享相同泛型类型声明并具有相等类型参数的任意两个实例。
(我猜这意味着,但不是??)getActualTypeArguments
getRawType
getOwnerType
我们从总合同中知道也必须实现,但是似乎没有规范这种方法应该产生什么值。java.lang.Object
hashCode
其他子类型 似乎都没有提到 或 ,除了每个值具有不同的实例之外。Type
equals
hashCode
Class
那么我应该在我的和中放入什么?equals
hashCode
(如果您想知道,我正在尝试用类型参数替换实际类型。因此,如果我知道在运行时是那么我想替换s,所以成为,成为,(可能发生!)成为,等等。TypeVariable<?>
T
Class<?>
String
Type
List<T>
List<String>
T[]
String[]
List<T>[]
List<String>[]
还是我必须创建自己的并行类型类型层次结构(不因假定的法律原因而重复)?(有图书馆吗?Type
编辑:关于我为什么需要这个,有几个问题。事实上,为什么要看泛型类型信息呢?
我从非泛型类/接口类型开始。(如果需要参数化类型,则始终可以使用新类添加间接寻址层。然后,我正在遵循字段或方法。这些可能引用参数化类型。只要他们不使用通配符,我仍然可以在面对诸如.List<String>
T
通过这种方式,我可以用高质量的静态打字做任何事情。这些动态类型均未在视线范围内进行检查。instanceof
在我的情况下,具体用法是序列化。但它可以适用于反射的任何其他合理使用,例如测试。
我用于下面的替换的当前代码状态。 是 .按“原样”显示快照。无论如何都没有整理(如果你不相信我)。typeMap
Map<String,Type>
throw null;
Type substitute(Type type) {
if (type instanceof TypeVariable<?>) {
Type actualType = typeMap.get(((TypeVariable<?>)type).getName());
if (actualType instanceof TypeVariable<?>) { throw null; }
if (actualType == null) {
throw new IllegalArgumentException("Type variable not found");
} else if (actualType instanceof TypeVariable<?>) {
throw new IllegalArgumentException("TypeVariable shouldn't substitute for a TypeVariable");
} else {
return actualType;
}
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)type;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
int len = actualTypeArguments.length;
Type[] actualActualTypeArguments = new Type[len];
for (int i=0; i<len; ++i) {
actualActualTypeArguments[i] = substitute(actualTypeArguments[i]);
}
// This will always be a Class, wont it? No higher-kinded types here, thank you very much.
Type actualRawType = substitute(parameterizedType.getRawType());
Type actualOwnerType = substitute(parameterizedType.getOwnerType());
return new ParameterizedType() {
public Type[] getActualTypeArguments() {
return actualActualTypeArguments.clone();
}
public Type getRawType() {
return actualRawType;
}
public Type getOwnerType() {
return actualOwnerType;
}
// Interface description requires equals method.
@Override public boolean equals(Object obj) {
if (!(obj instanceof ParameterizedType)) {
return false;
}
ParameterizedType other = (ParameterizedType)obj;
return
Arrays.equals(this.getActualTypeArguments(), other.getActualTypeArguments()) &&
this.getOwnerType().equals(other.getOwnerType()) &&
this.getRawType().equals(other.getRawType());
}
};
} else if (type instanceof GenericArrayType) {
GenericArrayType genericArrayType = (GenericArrayType)type;
Type componentType = genericArrayType.getGenericComponentType();
Type actualComponentType = substitute(componentType);
if (actualComponentType instanceof TypeVariable<?>) { throw null; }
return new GenericArrayType() {
// !! getTypeName? toString? equals? hashCode?
public Type getGenericComponentType() {
return actualComponentType;
}
// Apparently don't have to provide an equals, but we do need to.
@Override public boolean equals(Object obj) {
if (!(obj instanceof GenericArrayType)) {
return false;
}
GenericArrayType other = (GenericArrayType)obj;
return
this.getGenericComponentType().equals(other.getGenericComponentType());
}
};
} else {
return type;
}
}