ฉันจะบรรลุสิ่งนี้ได้อย่างไร
public class GenericClass<T>
{
public Type getMyType()
{
//How do I return the type of T?
}
}
ทุกสิ่งที่ฉันได้ลองมาแล้วจะส่งคืนประเภทเสมอObject
มากกว่าประเภทเฉพาะที่ใช้
ฉันจะบรรลุสิ่งนี้ได้อย่างไร
public class GenericClass<T>
{
public Type getMyType()
{
//How do I return the type of T?
}
}
ทุกสิ่งที่ฉันได้ลองมาแล้วจะส่งคืนประเภทเสมอObject
มากกว่าประเภทเฉพาะที่ใช้
คำตอบ:
ดังที่คนอื่น ๆ กล่าวถึงเป็นไปได้ผ่านการไตร่ตรองในบางสถานการณ์เท่านั้น
หากคุณต้องการประเภทจริง ๆ นี่เป็นรูปแบบการแก้ปัญหาตามปกติ (ประเภทปลอดภัย):
public class GenericClass<T> {
private final Class<T> type;
public GenericClass(Class<T> type) {
this.type = type;
}
public Class<T> getMyType() {
return this.type;
}
}
Foo foo1 = GetDao<Foo>(Foo.class).get(Foo.class, 1)
public static <T> GenericClass<T> of(Class<T> type) {...}
GenericClass<String> var = GenericClass.of(String.class)
ดีกว่านิดหน่อย
ฉันเห็นบางสิ่งเช่นนี้
private Class<T> persistentClass;
public Constructor() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
ในไฮเบอร์เนต GenericDataAccessObjectsตัวอย่าง
class A implements Comparable<String>
พารามิเตอร์ชนิดที่เกิดขึ้นจริงString
แต่มันก็ไม่สามารถบอกได้ว่าในพารามิเตอร์ชนิดที่เกิดขึ้นจริงSet<String> a = new TreeSet<String>()
String
ในความเป็นจริงข้อมูลพารามิเตอร์ประเภท "ลบ" หลังจากการรวบรวมตามที่อธิบายในคำตอบอื่น ๆ
java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
คำตอบนี้แล้ว
Class-Mate
จากคนแจ็คสัน ฉันเขียนส่วนสำคัญที่นี่gist.github.com/yunspace/930d4d40a787a1f6a7d1
(Class<T>) ((ParameterizedType)getClass().getSuperclass().getGenericSuperclass()).getActualTypeArguments()
อาร์กิวเมนต์ชนิดจริง
ยาชื่อสามัญจะไม่reifiedที่ใช้เวลา ซึ่งหมายความว่าข้อมูลจะไม่แสดง ณ เวลาทำการ
การเพิ่มยาชื่อสามัญให้กับ Java ในขณะที่ความเข้ากันได้ย้อนหลังเป็นทัวร์พลัง (คุณสามารถดูเอกสารน้ำเชื้อเกี่ยวกับมัน: ทำให้อนาคตที่ปลอดภัยสำหรับอดีต: เพิ่มความมีชีวิตชีวาให้กับภาษาการเขียนโปรแกรมภาษาจาวา )
มีวรรณกรรมมากมายเกี่ยวกับเรื่องนี้และบางคนไม่พอใจกับสถานะปัจจุบันบางคนบอกว่าจริง ๆ แล้วมันเป็นสิ่งล่อใจและไม่มีความต้องการที่แท้จริงสำหรับมัน คุณสามารถอ่านลิงก์ทั้งสองได้ฉันพบว่ามันน่าสนใจทีเดียว
ใช้ฝรั่ง
import com.google.common.reflect.TypeToken;
import java.lang.reflect.Type;
public abstract class GenericClass<T> {
private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) { };
private final Type type = typeToken.getType(); // or getRawType() to return Class<? super T>
public Type getType() {
return type;
}
public static void main(String[] args) {
GenericClass<String> example = new GenericClass<String>() { };
System.out.println(example.getType()); // => class java.lang.String
}
}
ในขณะที่ก่อนหน้านี้ฉันโพสต์ตัวอย่างเต็มรูปแบบบางคลาสรวมถึงคลาสนามธรรมและคลาสย่อยที่นี่ที่นี่
หมายเหตุ: สิ่งนี้ต้องการให้คุณสร้างอินสแตนซ์ย่อยของGenericClass
มันเพื่อให้สามารถผูกพารามิเตอร์ประเภทได้อย่างถูกต้อง T
มิฉะนั้นมันก็จะกลับเป็นประเภท
java.lang.IllegalArgumentException: class com.google.common.reflect.TypeToken isn't parameterized
รหัสของคุณพ่น ดังนั้นผมจึงเปลี่ยนสายไปnew TypeToken(getClass()) { }
new TypeToken<T>(getClass()) { }
ตอนนี้โค้ดทำงานได้ดี แต่ประเภทยังคงเป็น 'T' ดูสิ่งนี้: gist.github.com/m-manu/9cda9d8f9d53bead2035
default Type getParameterType() { final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {}; final Type type = typeToken.getType(); return type; }
GenericClass
เท่านั้นคุณควรทำให้คลาสabstract
นั้นใช้งานผิดดังนั้นจึงไม่ได้รวบรวม
แน่นอนว่าคุณสามารถ
Java ไม่ใช้ข้อมูล ณ เวลาทำงานเนื่องจากเหตุผลด้านความเข้ากันได้ย้อนหลัง แต่ข้อมูลนั้นแสดงเป็นเมทาดาทาจริงและสามารถเข้าถึงได้ผ่านการสะท้อนกลับ (แต่ยังไม่ได้ใช้สำหรับการตรวจสอบประเภท)
จาก API อย่างเป็นทางการ:
อย่างไรก็ตามสำหรับสถานการณ์ของคุณฉันจะไม่ใช้การสะท้อน โดยส่วนตัวฉันมีแนวโน้มที่จะใช้สิ่งนั้นสำหรับรหัสกรอบ ในกรณีของคุณฉันจะเพิ่มประเภทเป็นพารามิเตอร์ตัวสร้าง
Java generics เป็นส่วนใหญ่เวลารวบรวมซึ่งหมายความว่าข้อมูลประเภทจะหายไปที่รันไทม์
class GenericCls<T>
{
T t;
}
จะถูกรวบรวมไปยังสิ่งที่ชอบ
class GenericCls
{
Object o;
}
ในการรับข้อมูลชนิดที่รันไทม์คุณต้องเพิ่มมันเป็นอาร์กิวเมนต์ของ ctor
class GenericCls<T>
{
private Class<T> type;
public GenericCls(Class<T> cls)
{
type= cls;
}
Class<T> getType(){return type;}
}
ตัวอย่าง:
GenericCls<?> instance = new GenericCls<String>(String.class);
assert instance.getType() == String.class;
private final Class<T> type;
Type t = //String[]
public abstract class AbstractDao<T>
{
private final Class<T> persistentClass;
public AbstractDao()
{
this.persistentClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
}
}
ฉันใช้วิธีการติดตาม:
public class A<T> {
protected Class<T> clazz;
public A() {
this.clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getClazz() {
return clazz;
}
}
public class B extends A<C> {
/* ... */
public void anything() {
// here I may use getClazz();
}
}
ฉันไม่คิดว่าคุณจะทำได้ Java ใช้การลบประเภทเมื่อรวบรวมเพื่อให้โค้ดของคุณเข้ากันได้กับแอปพลิเคชันและไลบรารีที่สร้างไว้ล่วงหน้า
จากเอกสาร Oracle:
ลบประเภท
Generics ถูกนำมาใช้กับภาษา Java เพื่อให้การตรวจสอบประเภทที่เข้มงวดมากขึ้นในเวลารวบรวมและเพื่อสนับสนุนการเขียนโปรแกรมทั่วไป หากต้องการใช้งาน generics คอมไพเลอร์ Java จะใช้การลบประเภทกับ:
แทนที่พารามิเตอร์ประเภททั้งหมดในประเภททั่วไปด้วยขอบเขตหรือวัตถุหากพารามิเตอร์ประเภทนั้นไม่ได้ จำกัด ขอบเขต รหัสไบต์ที่ผลิตจึงมีเฉพาะคลาสอินเทอร์เฟซและวิธีการทั่วไปเท่านั้น ใส่ชนิดปลดเปลื้องหากจำเป็นเพื่อรักษาความปลอดภัยประเภท สร้างวิธีการบริดจ์เพื่อรักษาความหลากหลายในรูปแบบทั่วไปเพิ่มเติม การลบประเภททำให้มั่นใจได้ว่าจะไม่มีการสร้างคลาสใหม่สำหรับประเภทที่กำหนดพารามิเตอร์ ดังนั้นข้อมูลทั่วไปไม่มีค่าใช้จ่ายรันไทม์
http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
เทคนิคที่อธิบายไว้ในบทความนี้โดย Ian Robertson ได้ผลสำหรับฉัน
ในตัวอย่างรวดเร็วและสกปรกสั้น ๆ :
public abstract class AbstractDAO<T extends EntityInterface, U extends QueryCriteria, V>
{
/**
* Method returns class implementing EntityInterface which was used in class
* extending AbstractDAO
*
* @return Class<T extends EntityInterface>
*/
public Class<T> returnedClass()
{
return (Class<T>) getTypeArguments(AbstractDAO.class, getClass()).get(0);
}
/**
* 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;
}
}
/**
* Get the actual type arguments a child class has used to extend a generic
* base class.
*
* @param baseClass the base class
* @param childClass the child class
* @return a list of the raw classes for the actual type arguments.
*/
public static <T> List<Class<?>> getTypeArguments(
Class<T> baseClass, Class<? extends T> childClass)
{
Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
Type type = childClass;
// start walking up the inheritance hierarchy until we hit baseClass
while (!getClass(type).equals(baseClass)) {
if (type instanceof Class) {
// there is no useful information for us in raw types, so just keep going.
type = ((Class) type).getGenericSuperclass();
} else {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?> rawType = (Class) parameterizedType.getRawType();
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
TypeVariable<?>[] typeParameters = rawType.getTypeParameters();
for (int i = 0; i < actualTypeArguments.length; i++) {
resolvedTypes.put(typeParameters[i], actualTypeArguments[i]);
}
if (!rawType.equals(baseClass)) {
type = rawType.getGenericSuperclass();
}
}
}
// finally, for each actual type argument provided to baseClass, determine (if possible)
// the raw class for that type argument.
Type[] actualTypeArguments;
if (type instanceof Class) {
actualTypeArguments = ((Class) type).getTypeParameters();
} else {
actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
}
List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>();
// resolve types by chasing down type variables.
for (Type baseType : actualTypeArguments) {
while (resolvedTypes.containsKey(baseType)) {
baseType = resolvedTypes.get(baseType);
}
typeArgumentsAsClasses.add(getClass(baseType));
}
return typeArgumentsAsClasses;
}
}
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
ฉันคิดว่ามีวิธีแก้ไขปัญหาที่สวยงามอีกอย่างหนึ่ง
สิ่งที่คุณต้องการทำคือ "ผ่าน" ประเภทของพารามิเตอร์ประเภททั่วไปที่เพิ่มขึ้นจากคลาส concerete ไปยังซูเปอร์คลาส
หากคุณอนุญาตให้คุณนึกถึงประเภทของชั้นเรียนว่าเป็น "ข้อมูลเมตา" ในชั้นเรียนซึ่งจะแนะนำวิธีการ Java สำหรับการเข้ารหัสข้อมูลเมตาในตอนรันไทม์: คำอธิบายประกอบ
ก่อนกำหนดคำอธิบายประกอบที่กำหนดเองตามบรรทัดเหล่านี้:
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityAnnotation {
Class entityClass();
}
จากนั้นคุณสามารถเพิ่มคำอธิบายประกอบในคลาสย่อยของคุณ
@EntityAnnotation(entityClass = PassedGenericType.class)
public class Subclass<PassedGenericType> {...}
จากนั้นคุณสามารถใช้รหัสนี้เพื่อรับชนิดคลาสในคลาสพื้นฐานของคุณ:
import org.springframework.core.annotation.AnnotationUtils;
.
.
.
private Class getGenericParameterType() {
final Class aClass = this.getClass();
EntityAnnotation ne =
AnnotationUtils.findAnnotation(aClass, EntityAnnotation.class);
return ne.entityClass();
}
ข้อ จำกัด บางประการของวิธีนี้คือ:
PassedGenericType
) ในสองสถานที่มากกว่าหนึ่งซึ่งไม่ใช่ DRYนี่คือทางออกของฉัน:
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
public class GenericClass<T extends String> {
public static void main(String[] args) {
for (TypeVariable typeParam : GenericClass.class.getTypeParameters()) {
System.out.println(typeParam.getName());
for (Type bound : typeParam.getBounds()) {
System.out.println(bound);
}
}
}
}
นี่คือทางออกการทำงาน !!!
@SuppressWarnings("unchecked")
private Class<T> getGenericTypeClass() {
try {
String className = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].getTypeName();
Class<?> clazz = Class.forName(className);
return (Class<T>) clazz;
} catch (Exception e) {
throw new IllegalStateException("Class is not parametrized with generic type!!! Please use extends <> ");
}
}
หมายเหตุ:
สามารถใช้เป็นซูเปอร์
คลาสเท่านั้น 1. ต้องขยายด้วยคลาสที่พิมพ์ ( Child extends Generic<Integer>
)
หรือ
2. จะต้องสร้างเป็นการใช้งานแบบไม่ระบุชื่อ ( new Generic<Integer>() {};
)
คุณทำไม่ได้ หากคุณเพิ่มตัวแปรสมาชิกประเภท T ลงในคลาส (คุณไม่จำเป็นต้องกำหนดค่าเริ่มต้น) คุณสามารถใช้ตัวแปรนั้นเพื่อกู้คืนชนิด
นี่เป็นวิธีหนึ่งซึ่งฉันต้องใช้หนึ่งหรือสองครั้ง:
public abstract class GenericClass<T>{
public abstract Class<T> getMyType();
}
พร้อมด้วย
public class SpecificClass extends GenericClass<String>{
@Override
public Class<String> getMyType(){
return String.class;
}
}
วิธีแก้ปัญหาง่ายๆสำหรับรถแท็กซี่นี้จะเป็นดังนี้
public class GenericDemo<T>{
private T type;
GenericDemo(T t)
{
this.type = t;
}
public String getType()
{
return this.type.getClass().getName();
}
public static void main(String[] args)
{
GenericDemo<Integer> obj = new GenericDemo<Integer>(5);
System.out.println("Type: "+ obj.getType());
}
}
เพื่อให้คำตอบที่นี่ฉันต้องรับ ParametrizedType ของ MyGenericClass ไม่ว่าลำดับชั้นจะสูงแค่ไหนด้วยความช่วยเหลือของการเรียกซ้ำ:
private Class<T> getGenericTypeClass() {
return (Class<T>) (getParametrizedType(getClass())).getActualTypeArguments()[0];
}
private static ParameterizedType getParametrizedType(Class clazz){
if(clazz.getSuperclass().equals(MyGenericClass.class)){ // check that we are at the top of the hierarchy
return (ParameterizedType) clazz.getGenericSuperclass();
} else {
return getParametrizedType(clazz.getSuperclass());
}
}
นี่คือเคล็ดลับของฉัน:
public class Main {
public static void main(String[] args) throws Exception {
System.out.println(Main.<String> getClazz());
}
static <T> Class getClazz(T... param) {
return param.getClass().getComponentType();
}
}
T
เป็นตัวแปรประเภท ในกรณีที่T
เป็นตัวแปรชนิด varargs T
สร้างอาร์เรย์ของการลบออกของ ดูเช่นhttp://ideone.com/DIPNwd
ในกรณีที่คุณใช้เก็บตัวแปรโดยใช้ประเภททั่วไปคุณสามารถแก้ไขปัญหานี้ได้อย่างง่ายดายโดยเพิ่มเมธอด getClassType ดังนี้:
public class Constant<T> {
private T value;
@SuppressWarnings("unchecked")
public Class<T> getClassType () {
return ((Class<T>) value.getClass());
}
}
ฉันใช้วัตถุคลาสที่ให้ไว้ในภายหลังเพื่อตรวจสอบว่าเป็นตัวอย่างของคลาสที่กำหนดดังนี้:
Constant<?> constant = ...;
if (constant.getClassType().equals(Integer.class)) {
Constant<Integer> integerConstant = (Constant<Integer>)constant;
Integer value = integerConstant.getValue();
// ...
}
value
เป็นnull
? ประการที่สองจะเกิดอะไรขึ้นถ้าvalue
subclass ของT
? Constant<Number> c = new Constant<Number>(new Integer(0)); Class<Number> n = c.getClassType();
ผลตอบแทนที่ได้เมื่อมันควรจะกลับInteger.class
มันจะถูกต้องมากขึ้นที่จะกลับมาNumber.class
เป็นแต่ไม่ Class<? extends T>
Integer.class
Class<? extends Number>
Class<Number>
นี่คือทางออกของฉัน
public class GenericClass<T>
{
private Class<T> realType;
public GenericClass() {
findTypeArguments(getClass());
}
private void findTypeArguments(Type t) {
if (t instanceof ParameterizedType) {
Type[] typeArgs = ((ParameterizedType) t).getActualTypeArguments();
realType = (Class<T>) typeArgs[0];
} else {
Class c = (Class) t;
findTypeArguments(c.getGenericSuperclass());
}
}
public Type getMyType()
{
// How do I return the type of T? (your question)
return realType;
}
}
ไม่ว่าลำดับชั้นของคลาสของคุณจะมีอยู่กี่ระดับโซลูชันนี้ยังคงใช้งานได้เช่น:
public class FirstLevelChild<T> extends GenericClass<T> {
}
public class SecondLevelChild extends FirstLevelChild<String> {
}
ในกรณีนี้ getMyType () = java.lang.String
Exception in thread "main" java.lang.NullPointerException at Main$ClassA.findTypeArguments(Main.java:54) at Main$ClassA.findTypeArguments(Main.java:54) at Main$ClassA.findTypeArguments(Main.java:54) at Main$ClassA.<init>(Main.java:43) at Main.main(Main.java:61)
public static final Class<?> getGenericArgument(final Class<?> clazz)
{
return (Class<?>) ((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0];
}
นี่คือทางออกของฉัน ตัวอย่างควรอธิบาย ข้อกำหนดเพียงอย่างเดียวคือคลาสย่อยต้องตั้งค่าประเภททั่วไปไม่ใช่วัตถุ
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.Map;
public class TypeUtils {
/*** EXAMPLES ***/
public static class Class1<A, B, C> {
public A someA;
public B someB;
public C someC;
public Class<?> getAType() {
return getTypeParameterType(this.getClass(), Class1.class, 0);
}
public Class<?> getCType() {
return getTypeParameterType(this.getClass(), Class1.class, 2);
}
}
public static class Class2<D, A, B, E, C> extends Class1<A, B, C> {
public B someB;
public D someD;
public E someE;
}
public static class Class3<E, C> extends Class2<String, Integer, Double, E, C> {
public E someE;
}
public static class Class4 extends Class3<Boolean, Long> {
}
public static void test() throws NoSuchFieldException {
Class4 class4 = new Class4();
Class<?> typeA = class4.getAType(); // typeA = Integer
Class<?> typeC = class4.getCType(); // typeC = Long
Field fieldSomeA = class4.getClass().getField("someA");
Class<?> typeSomeA = TypeUtils.getFieldType(class4.getClass(), fieldSomeA); // typeSomeA = Integer
Field fieldSomeE = class4.getClass().getField("someE");
Class<?> typeSomeE = TypeUtils.getFieldType(class4.getClass(), fieldSomeE); // typeSomeE = Boolean
}
/*** UTILS ***/
public static Class<?> getTypeVariableType(Class<?> subClass, TypeVariable<?> typeVariable) {
Map<TypeVariable<?>, Type> subMap = new HashMap<>();
Class<?> superClass;
while ((superClass = subClass.getSuperclass()) != null) {
Map<TypeVariable<?>, Type> superMap = new HashMap<>();
Type superGeneric = subClass.getGenericSuperclass();
if (superGeneric instanceof ParameterizedType) {
TypeVariable<?>[] typeParams = superClass.getTypeParameters();
Type[] actualTypeArgs = ((ParameterizedType) superGeneric).getActualTypeArguments();
for (int i = 0; i < typeParams.length; i++) {
Type actualType = actualTypeArgs[i];
if (actualType instanceof TypeVariable) {
actualType = subMap.get(actualType);
}
if (typeVariable == typeParams[i]) return (Class<?>) actualType;
superMap.put(typeParams[i], actualType);
}
}
subClass = superClass;
subMap = superMap;
}
return null;
}
public static Class<?> getTypeParameterType(Class<?> subClass, Class<?> superClass, int typeParameterIndex) {
return TypeUtils.getTypeVariableType(subClass, superClass.getTypeParameters()[typeParameterIndex]);
}
public static Class<?> getFieldType(Class<?> clazz, AccessibleObject element) {
Class<?> type = null;
Type genericType = null;
if (element instanceof Field) {
type = ((Field) element).getType();
genericType = ((Field) element).getGenericType();
} else if (element instanceof Method) {
type = ((Method) element).getReturnType();
genericType = ((Method) element).getGenericReturnType();
}
if (genericType instanceof TypeVariable) {
Class<?> typeVariableType = TypeUtils.getTypeVariableType(clazz, (TypeVariable) genericType);
if (typeVariableType != null) {
type = typeVariableType;
}
}
return type;
}
}
ฉันทำเช่นเดียวกับ @Moesio Above แต่ใน Kotlin สามารถทำได้ด้วยวิธีนี้:
class A<T : SomeClass>() {
var someClassType : T
init(){
this.someClassType = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
}
}
มันอาจจะเป็นประโยชน์กับใครบางคน คุณสามารถใช้ java.lang.ref.WeakReference; ทางนี้:
class SomeClass<N>{
WeakReference<N> variableToGetTypeFrom;
N getType(){
return variableToGetTypeFrom.get();
}
}
WeakReference
? โปรดให้คำอธิบายกับคำตอบของคุณไม่ใช่แค่บางรหัส
SomeClass<MyClass>
คุณสามารถยกตัวอย่างSomeClass
และเรียกอินสแตนซ์ที่และมีรันไทม์จะเป็นgetType
MyClass
WeakReference
? สิ่งที่คุณพูดไม่แตกต่างจากคำตอบส่วนใหญ่
AtomicReference
, List
, Set
)
ฉันพบว่านี่เป็นวิธีแก้ปัญหาที่เข้าใจง่ายและอธิบายได้ง่าย
public class GenericClass<T> {
private Class classForT(T...t) {
return t.getClass().getComponentType();
}
public static void main(String[] args) {
GenericClass<String> g = new GenericClass<String>();
System.out.println(g.classForT());
System.out.println(String.class);
}
}
(T...t)
อธิบาย (นั่นเป็นสาเหตุที่รหัสนี้ใช้งานไม่ได้)