下面列出了怎么用java.lang.reflect.GenericArrayType的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Get the underlying class for a type, or null if the type is a variable
* type.
*
* @param type the type
* @return the underlying class
*/
public static Class<?> getClass(Type type) {
if (type instanceof Class) {
return (Class) type;
} else if (type instanceof ParameterizedType) {
return getClass(((ParameterizedType) type).getRawType());
} else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
Class<?> componentClass = getClass(componentType);
if (componentClass != null) {
return Array.newInstance(componentClass, 0).getClass();
} else {
return null;
}
} else {
return null;
}
}
@Override
final Object fromNonNullOpenValue(Object openValue)
throws InvalidObjectException {
final Object[] openArray = (Object[]) openValue;
final Type javaType = getJavaType();
final Object[] valueArray;
final Type componentType;
if (javaType instanceof GenericArrayType) {
componentType =
((GenericArrayType) javaType).getGenericComponentType();
} else if (javaType instanceof Class<?> &&
((Class<?>) javaType).isArray()) {
componentType = ((Class<?>) javaType).getComponentType();
} else {
throw new IllegalArgumentException("Not an array: " +
javaType);
}
valueArray = (Object[]) Array.newInstance((Class<?>) componentType,
openArray.length);
for (int i = 0; i < openArray.length; i++)
valueArray[i] = elementMapping.fromOpenValue(openArray[i]);
return valueArray;
}
public static Class<?> getGenericClass(Class<?> cls, int i) {
try {
ParameterizedType parameterizedType = ((ParameterizedType) cls.getGenericInterfaces()[0]);
Object genericClass = parameterizedType.getActualTypeArguments()[i];
if (genericClass instanceof ParameterizedType) { // 处理多级泛型
return (Class<?>) ((ParameterizedType) genericClass).getRawType();
} else if (genericClass instanceof GenericArrayType) { // 处理数组泛型
return (Class<?>) ((GenericArrayType) genericClass).getGenericComponentType();
} else if (genericClass != null) {
return (Class<?>) genericClass;
}
} catch (Throwable e) {
toString(e);
}
if (cls.getSuperclass() != null) {
return getGenericClass(cls.getSuperclass(), i);
} else {
throw new IllegalArgumentException(cls.getName() + " generic type undefined!");
}
}
/**
* Converts a binding for a {@code Key<TypeLiteral<T>>} to the value {@code TypeLiteral<T>}. It's
* a bit awkward because we have to pull out the inner type in the type literal.
*/
private <T> BindingImpl<TypeLiteral<T>> createTypeLiteralBinding(
Key<TypeLiteral<T>> key, Errors errors) throws ErrorsException {
Type typeLiteralType = key.getTypeLiteral().getType();
if (!(typeLiteralType instanceof ParameterizedType)) {
throw errors.cannotInjectRawTypeLiteral().toException();
}
ParameterizedType parameterizedType = (ParameterizedType) typeLiteralType;
Type innerType = parameterizedType.getActualTypeArguments()[0];
// this is unfortunate. We don't support building TypeLiterals for type variable like 'T'. If
// this proves problematic, we can probably fix TypeLiteral to support type variables
if (!(innerType instanceof Class)
&& !(innerType instanceof GenericArrayType)
&& !(innerType instanceof ParameterizedType)) {
throw errors.cannotInjectTypeLiteralOf(innerType).toException();
}
@SuppressWarnings("unchecked") // by definition, innerType == T, so this is safe
TypeLiteral<T> value = (TypeLiteral<T>) TypeLiteral.get(innerType);
InternalFactory<TypeLiteral<T>> factory = new ConstantFactory<>(
Initializables.of(value));
return new InstanceBindingImpl<>(this, key, SourceProvider.UNKNOWN_SOURCE,
factory, emptySet(), value);
}
private String toString(Type type, boolean qualify) {
visited.add(type);
String result=null;
if (type instanceof TypeVariable) {
result=printTypeVariable((TypeVariable<?>) type,qualify);
} else if (type instanceof ParameterizedType) {
result=printParameterizedType((ParameterizedType) type,qualify);
} else if (type instanceof Class) {
result=printClass((Class<?>) type,qualify);
} else if (type instanceof GenericArrayType) {
result=printGenericArrayDeclaration((GenericArrayType) type,qualify);
} else if (type instanceof WildcardType) {
result=printWildcardType((WildcardType) type);
} else {
throw new IllegalStateException("Unknown type '"+type+"'");
}
return result;
}
@Override
public boolean supports(Type genericType) {
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
if (JAXBElement.class == parameterizedType.getRawType() &&
parameterizedType.getActualTypeArguments().length == 1) {
Type typeArgument = parameterizedType.getActualTypeArguments()[0];
if (typeArgument instanceof Class) {
Class<?> classArgument = (Class<?>) typeArgument;
return ((classArgument.isArray() && Byte.TYPE == classArgument.getComponentType()) ||
isPrimitiveWrapper(classArgument) || isStandardClass(classArgument) ||
supportsInternal(classArgument, false));
}
else if (typeArgument instanceof GenericArrayType) {
GenericArrayType arrayType = (GenericArrayType) typeArgument;
return (Byte.TYPE == arrayType.getGenericComponentType());
}
}
}
else if (genericType instanceof Class) {
Class<?> clazz = (Class<?>) genericType;
return supportsInternal(clazz, this.checkForXmlRootElement);
}
return false;
}
@SuppressWarnings("unchecked")
public static <T> Class<T> getFieldArgument(Class<?> genericCls, String fieldName) {
try {
Type generic = FieldUtils.getField(genericCls, fieldName).getGenericType();
TypeToken<?> token = TypeToken.of(genericCls).resolveType(generic);
Type fieldType = token.getType();
Type argument = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
if (argument instanceof GenericArrayType) {
return (Class<T>) TypeToken.of(argument).getRawType();
}
return (Class<T>) argument;
} catch (Throwable e) {
throw new IllegalStateException("Failed to get generic argument.", e);
}
}
@Override
final Object fromNonNullOpenValue(Object openValue)
throws InvalidObjectException {
final Object[] openArray = (Object[]) openValue;
final Type javaType = getJavaType();
final Object[] valueArray;
final Type componentType;
if (javaType instanceof GenericArrayType) {
componentType =
((GenericArrayType) javaType).getGenericComponentType();
} else if (javaType instanceof Class<?> &&
((Class<?>) javaType).isArray()) {
componentType = ((Class<?>) javaType).getComponentType();
} else {
throw new IllegalArgumentException("Not an array: " +
javaType);
}
valueArray = (Object[]) Array.newInstance((Class<?>) componentType,
openArray.length);
for (int i = 0; i < openArray.length; i++)
valueArray[i] = elementMapping.fromOpenValue(openArray[i]);
return valueArray;
}
/**
* Get the underlying class for a type, or null if the type is a variable type.
* @param type the type
* @return the underlying class
*/
public static Class<?> getClass(Type type) {
if (type instanceof Class) {
return (Class) type;
}
else if (type instanceof ParameterizedType) {
return getClass(((ParameterizedType) type).getRawType());
}
else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
Class<?> componentClass = getClass(componentType);
if (componentClass != null ) {
return Array.newInstance(componentClass, 0).getClass();
}
else {
return null;
}
}
else {
return null;
}
}
static String typeName(Type type) {
if (type instanceof Class<?>) {
Class<?> c = (Class<?>) type;
if (c.isArray())
return typeName(c.getComponentType()) + "[]";
else
return c.getName();
} else if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) type;
return typeName(gat.getGenericComponentType()) + "[]";
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
StringBuilder sb = new StringBuilder();
sb.append(typeName(pt.getRawType())).append("<");
String sep = "";
for (Type t : pt.getActualTypeArguments()) {
sb.append(sep).append(typeName(t));
sep = ", ";
}
return sb.append(">").toString();
} else
return "???";
}
@Override
final Object fromNonNullOpenValue(Object openValue)
throws InvalidObjectException {
final Object[] openArray = (Object[]) openValue;
final Type javaType = getJavaType();
final Object[] valueArray;
final Type componentType;
if (javaType instanceof GenericArrayType) {
componentType =
((GenericArrayType) javaType).getGenericComponentType();
} else if (javaType instanceof Class<?> &&
((Class<?>) javaType).isArray()) {
componentType = ((Class<?>) javaType).getComponentType();
} else {
throw new IllegalArgumentException("Not an array: " +
javaType);
}
valueArray = (Object[]) Array.newInstance((Class<?>) componentType,
openArray.length);
for (int i = 0; i < openArray.length; i++)
valueArray[i] = elementMapping.fromOpenValue(openArray[i]);
return valueArray;
}
static String typeName(Type type) {
if (type instanceof Class<?>) {
Class<?> c = (Class<?>) type;
if (c.isArray())
return typeName(c.getComponentType()) + "[]";
else
return c.getName();
} else if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) type;
return typeName(gat.getGenericComponentType()) + "[]";
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
StringBuilder sb = new StringBuilder();
sb.append(typeName(pt.getRawType())).append("<");
String sep = "";
for (Type t : pt.getActualTypeArguments()) {
sb.append(sep).append(typeName(t));
sep = ", ";
}
return sb.append(">").toString();
} else
return "???";
}
static String typeName(Type type) {
if (type instanceof Class<?>) {
Class<?> c = (Class<?>) type;
if (c.isArray())
return typeName(c.getComponentType()) + "[]";
else
return c.getName();
} else if (type instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) type;
return typeName(gat.getGenericComponentType()) + "[]";
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
StringBuilder sb = new StringBuilder();
sb.append(typeName(pt.getRawType())).append("<");
String sep = "";
for (Type t : pt.getActualTypeArguments()) {
sb.append(sep).append(typeName(t));
sep = ", ";
}
return sb.append(">").toString();
} else
return "???";
}
public Deserializer getDeserializer(Type type) {
Deserializer deserializer = deserializerMap.get(type);
if (deserializer != null) {
return deserializer;
}
if (type instanceof Class<?>) {
return getDeserializer((Class<?>) type, type);
}
if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class<?>) {
return getDeserializer((Class<?>) rawType, type);
} else {
return getDeserializer(rawType);
}
}
if (type instanceof GenericArrayType) {
return ArrayDeserializer.INSTANCE;
}
throw new IllegalArgumentException("can't get the Deserializer by " + type);
}
static Class<?> getArrayComponentType(Type cls) {
if (cls instanceof Class) {
if (((Class<?>)cls).isArray()) {
return ((Class<?>)cls).getComponentType();
}
return (Class<?>)cls;
} else if (cls instanceof ParameterizedType) {
for (Type t2 : ((ParameterizedType)cls).getActualTypeArguments()) {
return getArrayComponentType(t2);
}
} else if (cls instanceof GenericArrayType) {
GenericArrayType gt = (GenericArrayType)cls;
Class<?> ct = (Class<?>) gt.getGenericComponentType();
return Array.newInstance(ct, 0).getClass();
}
return null;
}
/**
* <p>Checks if the subject type may be implicitly cast to the target type
* following the Java generics rules.</p>
*
* @param type the subject type to be assigned to the target type
* @param toType the target type
* @param typeVarAssigns optional map of type variable assignments
* @return {@code true} if {@code type} is assignable to {@code toType}.
*/
private static boolean isAssignable(final Type type, final Type toType,
final Map<TypeVariable<?>, Type> typeVarAssigns) {
if (toType == null || toType instanceof Class<?>) {
return isAssignable(type, (Class<?>) toType);
}
if (toType instanceof ParameterizedType) {
return isAssignable(type, (ParameterizedType) toType, typeVarAssigns);
}
if (toType instanceof GenericArrayType) {
return isAssignable(type, (GenericArrayType) toType, typeVarAssigns);
}
if (toType instanceof WildcardType) {
return isAssignable(type, (WildcardType) toType, typeVarAssigns);
}
if (toType instanceof TypeVariable<?>) {
return isAssignable(type, (TypeVariable<?>) toType, typeVarAssigns);
}
throw new IllegalStateException("found an unhandled type: " + toType);
}
/**
* Adds any types exposed from the given array type. The array type itself is not added. The cause
* of the exposure of the underlying type is considered whatever type exposed the array type.
*/
private void addExposedTypes(GenericArrayType type, Class<?> cause) {
if (done(type)) {
return;
}
visit(type);
LOG.debug(
"Adding exposed types from {}, which is the component type on generic array type {}",
type.getGenericComponentType(),
type);
addExposedTypes(type.getGenericComponentType(), cause);
}
public static Class<?> getRawType(Type type) {
if (type instanceof Class<?>) {
// type is a normal class.
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class.
// Neal isn't either but suspects some pathological case related
// to nested classes exists.
Type rawType = parameterizedType.getRawType();
if (!(rawType instanceof Class)) {
throw new IllegalArgumentException(
"Expected a Class, but <" + type + "> is of type " + type.getClass().getName()
);
}
return (Class<?>) rawType;
} else if (type instanceof GenericArrayType) {
// TODO: Is this sufficient?
return Object[].class;
} else if (type instanceof TypeVariable) {
// we could use the variable's bounds, but that'll won't work if there are multiple.
// having a raw type that's more general than necessary is okay
return Object.class;
} else {
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
}
}
private String printGenericArrayDeclaration(GenericArrayType type, boolean qualify) {
String componentType = toString(type.getGenericComponentType(),qualify);
if(componentType.indexOf(' ')>0) { // NOSONAR
return String.format("(%s)[]",componentType);
} else {
return componentType.concat("[]");
}
}
@Override
public boolean equals(Object o)
{
if (o == this)
return true;
else if (o instanceof GenericArrayType) {
GenericArrayType type = (GenericArrayType) o;
return getGenericComponentType().equals(type.getGenericComponentType());
}
else
return false;
}
private static void check2(Type t, String what) {
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
check(pt.getActualTypeArguments(), "type argument", what);
} else if (t instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) t;
check(tv.getBounds(), "bound", what);
GenericDeclaration gd = tv.getGenericDeclaration();
if (gd instanceof Type)
check((Type) gd, "declaration containing " + what);
} else if (t instanceof WildcardType) {
WildcardType wt = (WildcardType) t;
check(wt.getLowerBounds(), "lower bound", "wildcard type in " + what);
check(wt.getUpperBounds(), "upper bound", "wildcard type in " + what);
} else if (t instanceof Class<?>) {
Class<?> c = (Class<?>) t;
check(c.getGenericInterfaces(), "superinterface", c.toString());
check(c.getGenericSuperclass(), "superclass of " + c);
check(c.getTypeParameters(), "type parameter", c.toString());
} else if (t instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) t;
Type comp = gat.getGenericComponentType();
if (comp instanceof Class) {
fail("Type " + t + " uses GenericArrayType when plain " +
"array would do, in " + what);
} else
check(comp, "component type of " + what);
} else {
fail("TEST BUG: mutant Type " + t + " (a " + t.getClass().getName() + ")");
}
}
private static void check2(Type t, String what) {
if (t instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) t;
check(pt.getActualTypeArguments(), "type argument", what);
} else if (t instanceof TypeVariable) {
TypeVariable<?> tv = (TypeVariable<?>) t;
check(tv.getBounds(), "bound", what);
GenericDeclaration gd = tv.getGenericDeclaration();
if (gd instanceof Type)
check((Type) gd, "declaration containing " + what);
} else if (t instanceof WildcardType) {
WildcardType wt = (WildcardType) t;
check(wt.getLowerBounds(), "lower bound", "wildcard type in " + what);
check(wt.getUpperBounds(), "upper bound", "wildcard type in " + what);
} else if (t instanceof Class<?>) {
Class<?> c = (Class<?>) t;
check(c.getGenericInterfaces(), "superinterface", c.toString());
check(c.getGenericSuperclass(), "superclass of " + c);
check(c.getTypeParameters(), "type parameter", c.toString());
} else if (t instanceof GenericArrayType) {
GenericArrayType gat = (GenericArrayType) t;
Type comp = gat.getGenericComponentType();
if (comp instanceof Class) {
fail("Type " + t + " uses GenericArrayType when plain " +
"array would do, in " + what);
} else
check(comp, "component type of " + what);
} else {
fail("TEST BUG: mutant Type " + t + " (a " + t.getClass().getName() + ")");
}
}
private Object encodeMap(){
//for Map<K,V>, first to check the type of V
ParameterizedType paramType = (ParameterizedType)field.getGenericType();
Type[] types = paramType.getActualTypeArguments();
boolean isArray = false;
boolean isCollection = false;
boolean isSingle = false;
if(types[1] instanceof GenericArrayType){
isArray = true;
}else if(types[1] instanceof ParameterizedType){
isCollection = true;
}else{
//in JDK8, type[1] of array, is a class, not array
Class<?> actualType = FieldUtil.getClassOfType(types[1]);
if(actualType.isArray()){
isArray = true;
}else{
isSingle = true;
}
}
//encode value by different type of V
Map map = (Map)value;
Map result = new HashMap();
for(Object key : map.keySet()){
Object entryValue = map.get(key);
if(entryValue == null){
result.put(key, null);
continue;
}
if(isSingle){
result.put(key, MapperUtil.toDBObject(entryValue));
}else if(isArray){
result.put(key, encodeArray(entryValue));
}else if(isCollection){
result.put(key, encodeCollection(entryValue));
}
}
return result;
}
static Class<?> getRawType(Type type) {
if (type instanceof Class<?>) {
// type is a normal class.
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but
// suspects some pathological case related to nested classes exists.
Type rawType = parameterizedType.getRawType();
return (Class<?>) rawType;
} else if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
return Array.newInstance(getRawType(componentType), 0).getClass();
} else if (type instanceof TypeVariable) {
// We could use the variable's bounds, but that won't work if there are multiple. having a raw
// type that's more general than necessary is okay.
return Object.class;
} else if (type instanceof WildcardType) {
return getRawType(((WildcardType) type).getUpperBounds()[0]);
} else {
String className = type == null ? "null" : type.getClass().getName();
throw new IllegalArgumentException(
"Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <"
+ type
+ "> is of type "
+ className);
}
}
@NotNull
private Type getArrayType(@NotNull Type component, int arrayDeepness) {
if (arrayDeepness == 0) {
return component;
}
return (GenericArrayType) () -> getArrayType(component, arrayDeepness - 1);
}
public static <T, C> ObjectArrayTypeInfo<T, C> getInfoFor(Type type, TypeInformation<C> componentInfo) {
// generic array type e.g. for Tuples
if (type instanceof GenericArrayType) {
GenericArrayType genericArray = (GenericArrayType) type;
return new ObjectArrayTypeInfo<T, C>(type, genericArray.getGenericComponentType(), componentInfo);
}
// for tuples without generics (e.g. generated by the TypeInformation parser)
else if (type instanceof Class<?> && ((Class<?>) type).isArray() && Tuple.class.isAssignableFrom(((Class<?>) type).getComponentType())
&& type != Tuple.class) {
return new ObjectArrayTypeInfo<T, C>(type, ((Class<?>) type).getComponentType(), componentInfo);
}
return getInfoFor(type);
}
@SuppressWarnings("unchecked")
private static <T> Class<T> rawTypeOf(final Type type) {
if (type instanceof Class<?>) {
return (Class<T>) type;
} else if (type instanceof ParameterizedType) {
return rawTypeOf(((ParameterizedType) type).getRawType());
} else if (type instanceof GenericArrayType) {
return (Class<T>) Array.newInstance(rawTypeOf(((GenericArrayType) type).getGenericComponentType()), 0).getClass();
} else {
throw InjectionMessages.msg.noRawType(type);
}
}
public boolean isArrayButNotByteArray(Type t) {
if (t instanceof Class) {
Class c = (Class) t;
return c.isArray() && c != byte[].class;
}
if (t instanceof GenericArrayType) {
t = ((GenericArrayType) t).getGenericComponentType();
return t != Byte.TYPE;
}
return false;
}
public Type resolveType(GenericArrayType type) {
Type genericComponentType = type.getGenericComponentType();
// try to resolve the type
Type resolvedType = genericComponentType;
if (genericComponentType instanceof TypeVariable<?>) {
resolvedType = resolveType((TypeVariable<?>) genericComponentType);
}
if (genericComponentType instanceof ParameterizedType) {
resolvedType = resolveType((ParameterizedType) genericComponentType);
}
if (genericComponentType instanceof GenericArrayType) {
resolvedType = resolveType((GenericArrayType) genericComponentType);
}
/*
* If the generic component type resolved to a class (e.g. String) we return [Ljava.lang.String; (the class representing
* the
* array) instead of GenericArrayType with String as its generic component type.
*/
if (resolvedType instanceof Class<?>) {
Class<?> componentClass = (Class<?>) resolvedType;
return Array.newInstance(componentClass, 0).getClass();
}
/*
* This identity check is intentional. If the identity is different it indicates that we succeeded in resolving the type
* and a new GenericArrayType with resolved generic component type is returned. Otherwise, we were not able to resolve
* the type and therefore we do not create a new GenericArrayType.
*/
if (resolvedType == genericComponentType) {
return type;
} else {
return new GenericArrayTypeImpl(resolvedType);
}
}
@Test
public void testEquals_ParameterizedType_and_GenericArrayType() throws Exception {
//when
boolean result = Types.equals(ParameterizedType.class, GenericArrayType.class);
//then
assertFalse("ParameterizedType and GenericArrayType must not be equal", result);
}