Skip to content

Commit

Permalink
Merge pull request alibaba#154 from kraity/main
Browse files Browse the repository at this point in the history
reformet and inline codes  for TypeReference.class
  • Loading branch information
wenshao authored May 3, 2022
2 parents fffffbb + c78237f commit 2ca2f5a
Showing 1 changed file with 71 additions and 75 deletions.
146 changes: 71 additions & 75 deletions core/src/main/java/com/alibaba/fastjson2/TypeReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Represents a generic type {@code T}. Java doesn't yet provide a way to
Expand Down Expand Up @@ -61,16 +59,19 @@ public TypeReference(Type type, boolean raw) {
this.rawType = (Class<? super T>) BeanUtils.getRawType(type);
}

private static final Map<Class<?>, String> primitiveTypeMap = new HashMap<Class<?>, String>(8) {{
put(boolean.class, "Z");
put(char.class, "C");
put(byte.class, "B");
put(short.class, "S");
put(int.class, "I");
put(long.class, "J");
put(float.class, "F");
put(double.class, "D");
}};
/**
* @param actualTypeArguments an array of Type objects representing the actual type arguments to this type
* @since 2.0.2
*/
@SuppressWarnings("unchecked")
public TypeReference(Type... actualTypeArguments) {
Class<?> thisClass = getClass();
Type superClass = thisClass.getGenericSuperclass();
ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];

type = canonicalize(thisClass, argType, actualTypeArguments, 0);
rawType = (Class<? super T>) BeanUtils.getRawType(type);
}

/**
* Get the {@link Type}
Expand Down Expand Up @@ -149,85 +150,80 @@ public static TypeReference<?> get(Type type) {
};
}

protected TypeReference(Type... actualTypeArguments) {
Class<?> thisClass = this.getClass();
Type superClass = thisClass.getGenericSuperclass();

ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type rawType = argType.getRawType();
Type[] argTypes = argType.getActualTypeArguments();
/**
* @param thisClass this class
* @param type the parameterizedType
* @param actualTypeArguments an array of Type objects representing the actual type arguments to this type
* @param actualIndex the actual index
* @since 2.0.3
*/
private static Type canonicalize(Class<?> thisClass, ParameterizedType type, Type[] actualTypeArguments, int actualIndex) {
Type rawType = type.getRawType();
Type[] argTypes = type.getActualTypeArguments();

int actualIndex = 0;
for (int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable &&
actualIndex < actualTypeArguments.length) {
actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}

// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
}

// 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
if (argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
}
}

this.type = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
this.rawType = (Class<? super T>) BeanUtils.getRawType(type);
}

static Type checkPrimitiveArray(GenericArrayType genericArrayType) {
Type clz = genericArrayType;
Type genericComponentType = genericArrayType.getGenericComponentType();
Type componentType = argTypes[i];
StringBuilder sb = new StringBuilder();

String prefix = "[";
while (genericComponentType instanceof GenericArrayType) {
genericComponentType = ((GenericArrayType) genericComponentType)
.getGenericComponentType();
prefix += prefix;
}
while (componentType instanceof GenericArrayType) {
sb.append('[');
componentType = ((GenericArrayType) componentType).getGenericComponentType();
}

if (genericComponentType instanceof Class<?>) {
Class<?> ck = (Class<?>) genericComponentType;
if (ck.isPrimitive()) {
try {
String postfix = primitiveTypeMap.get(ck);
if (postfix != null) {
clz = Class.forName(prefix + postfix);
if (componentType instanceof Class<?>) {
Class<?> cls = (Class<?>) componentType;
Loader:
if (cls.isPrimitive()) {
if (cls == int.class) {
sb.append('I');
} else if (cls == long.class) {
sb.append('J');
} else if (cls == float.class) {
sb.append('F');
} else if (cls == double.class) {
sb.append('D');
} else if (cls == boolean.class) {
sb.append('Z');
} else if (cls == char.class) {
sb.append('C');
} else if (cls == byte.class) {
sb.append('B');
} else if (cls == short.class) {
sb.append('S');
} else {
break Loader;
}

try {
argTypes[i] = Class.forName(
sb.toString()
);
} catch (ClassNotFoundException e) {
// nothing
}
}
} catch (ClassNotFoundException ignored) {
}
}
}

return clz;
}

private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) {
Class<?> thisClass = this.getClass();
Type rawType = type.getRawType();
Type[] argTypes = type.getActualTypeArguments();

for (int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}

// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
}

// 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型
// if it is a ParameterizedType,
// iterate to find the real Type
if (argTypes[i] instanceof ParameterizedType) {
argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex);
argTypes[i] = canonicalize(
thisClass, (ParameterizedType) argTypes[i],
actualTypeArguments, actualIndex
);
}
}

return new ParameterizedTypeImpl(argTypes, thisClass, rawType);
return new ParameterizedTypeImpl(
argTypes, thisClass, rawType
);
}
}

0 comments on commit 2ca2f5a

Please sign in to comment.