mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 10:30:42 +00:00
create TypeToken
This commit is contained in:
@@ -4,8 +4,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
import java.lang.reflect.WildcardType;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Stream;
|
||||
@@ -33,4 +39,29 @@ public final class ReflectionUtil {
|
||||
T a = element.getAnnotation(annotation);
|
||||
if(a != null) operation.accept(a);
|
||||
}
|
||||
|
||||
public static Class<?> getRawType(Type type) {
|
||||
if (type instanceof Class<?>) {
|
||||
return (Class<?>) type;
|
||||
} else if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
public static String typeToString(Type type) {
|
||||
return type instanceof Class ? ((Class<?>) type).getName() : type.toString();
|
||||
}
|
||||
}
|
||||
|
||||
104
common/api/src/main/java/com/dfsek/terra/api/util/TypeToken.java
Normal file
104
common/api/src/main/java/com/dfsek/terra/api/util/TypeToken.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TypeToken<T> {
|
||||
final Class<? super T> rawType;
|
||||
final Type type;
|
||||
final int hashCode;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected TypeToken() {
|
||||
this.type = getSuperclassTypeParameter(getClass());
|
||||
this.rawType = (Class<? super T>) ReflectionUtil.getRawType(type);
|
||||
this.hashCode = type.hashCode();
|
||||
}
|
||||
|
||||
|
||||
static Type getSuperclassTypeParameter(Class<?> subclass) {
|
||||
Type superclass = subclass.getGenericSuperclass();
|
||||
if(superclass instanceof Class) {
|
||||
throw new RuntimeException("Missing type parameter.");
|
||||
}
|
||||
ParameterizedType parameterized = (ParameterizedType) superclass;
|
||||
return parameterized.getActualTypeArguments()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw (non-generic) type for this type.
|
||||
*/
|
||||
public final Class<? super T> getRawType() {
|
||||
return rawType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets underlying {@code Type} instance.
|
||||
*/
|
||||
public final Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return this.hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object o) {
|
||||
return o instanceof TypeToken<?>
|
||||
&& equals(type, ((TypeToken<?>) o).type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return ReflectionUtil.typeToString(type);
|
||||
}
|
||||
|
||||
public static boolean equals(Type a, Type b) {
|
||||
if(a == b) {
|
||||
return true;
|
||||
} else if(a instanceof Class) {
|
||||
return a.equals(b);
|
||||
} else if(a instanceof ParameterizedType) {
|
||||
if(!(b instanceof ParameterizedType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ParameterizedType pa = (ParameterizedType) a;
|
||||
ParameterizedType pb = (ParameterizedType) b;
|
||||
return Objects.equals(pa.getOwnerType(), pb.getOwnerType())
|
||||
&& pa.getRawType().equals(pb.getRawType())
|
||||
&& Arrays.equals(pa.getActualTypeArguments(), pb.getActualTypeArguments());
|
||||
} else if(a instanceof GenericArrayType) {
|
||||
if(!(b instanceof GenericArrayType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GenericArrayType ga = (GenericArrayType) a;
|
||||
GenericArrayType gb = (GenericArrayType) b;
|
||||
return equals(ga.getGenericComponentType(), gb.getGenericComponentType());
|
||||
} else if(a instanceof WildcardType) {
|
||||
if(!(b instanceof WildcardType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WildcardType wa = (WildcardType) a;
|
||||
WildcardType wb = (WildcardType) b;
|
||||
return Arrays.equals(wa.getUpperBounds(), wb.getUpperBounds())
|
||||
&& Arrays.equals(wa.getLowerBounds(), wb.getLowerBounds());
|
||||
} else if(a instanceof TypeVariable) {
|
||||
if(!(b instanceof TypeVariable)) {
|
||||
return false;
|
||||
}
|
||||
TypeVariable<?> va = (TypeVariable<?>) a;
|
||||
TypeVariable<?> vb = (TypeVariable<?>) b;
|
||||
return va.getGenericDeclaration() == vb.getGenericDeclaration()
|
||||
&& va.getName().equals(vb.getName());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user