我怎样才能做到这一点呢?
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类型,而不是使用的特定类型。
当前回答
当然,你可以。
出于向后兼容性的考虑,Java在运行时不使用这些信息。但是信息实际上是以元数据的形式呈现的,并且可以通过反射访问(但是它仍然不用于类型检查)。
来自官方API:
http://download.oracle.com/javase/6/docs/api/java/lang/reflect/ParameterizedType.html#getActualTypeArguments%28%29
但是,对于您的场景,我不会使用反射。我个人更倾向于将其用于框架代码。在你的例子中,我只是将类型作为构造函数参数添加。
其他回答
我不认为你可以,Java在编译时使用类型擦除,这样你的代码就可以与在泛型之前创建的应用程序和库兼容。
来自Oracle文档:
Type Erasure Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to: Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods. Insert type casts if necessary to preserve type safety. Generate bridge methods to preserve polymorphism in extended generic types. Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
这是我的解决方案:
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);
}
}
}
}
使用返回类类型的抽象方法,然后在该类中使用它,无论在何处扩展泛型类,都必须实现该抽象方法以返回所需的类类型
public class AbsractService<T>{
public abstract Class<T> getClassType ();
.......
}
在运行时
class AnimalService extends AbstractService<Animal>{
@Override
public Class<Animal> getClassType (){
return Animal.class;
}
.....
}
如果不能更改泛型类并使用本页中已经解释的方法之一,那么简单的方法是根据运行时实例类名获取类型类。
Class getType(GenericType runtimeClassMember){
if (ClassA.class.equals(runtimeClassMember.getClass()){
return TypeForClassA.class;
} else if (ClassB.class.equals(runtimeClassMember.getClass()){
return TypeForClassB.class;
}
//throw an expectation or do whatever you want for the cases not described in the if section.
}
我做了相同的@Moesio上面,但在Kotlin可以这样做:
class A<T : SomeClass>() {
var someClassType : T
init(){
this.someClassType = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<T>
}
}