2012-02-23 85 views
3

我有一个通用的基础类:泛型类 - 的getClass()的getName()

public class BaseLabel<T> extends JXLabel { 
    private static final long serialVersionUID = 1L; 

    public BaseLabel() { 
     System.out.println(T.class.getClass().getName()); //error 
    }  
} 

和儿童类:

public class ChildLabel extends BaseLabel<ChildLabel> { 
    private static final long serialVersionUID = 2L; 

    public ChildLabel() { 

    }  
} 

我收到编译错误。

有没有什么办法从BaseClass的构造函数中获取实际的类名。在这里,通过实际的课程,我指的是我将要实例化的那个课程。

例如,我正在实例化ChildClass,ChildClass clz = new ChildClass();

然后println()将打印package.ChildClass

在此先感谢。


的编译错误是:

cannot select from a type variable System.out.println(T.class.getClass().getSimpleName()); 

如果我把从abstract BaseClass的构造this.getClass.getSimpleName()。它正在打印ChildClass

为什么?

这是由于,因为我实例化ChildClass所以这是指向ChildClass的对象。

+3

您要求的信息在编译时不可用,所以据我所知,您要做的事情是不可能的。但即使在运行时,您也会遇到Java获取此信息的一般限制。请阅读本文,特别是有关泛型和类型删除的部分:[Java理论与实践:泛型](http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html) – 2012-02-23 16:24:45

+0

什么是编译错误说? – Thomas 2012-02-23 16:25:13

+0

您正在导入JXLabel吗? – ewok 2012-02-23 16:27:18

回答

7

丑吗?是

import java.lang.reflect.ParameterizedType; 


public class GenericClass<T> { 

    public GenericClass() { 
     System.out.println(getClass().getGenericSuperclass()); //output: GenericClass<Foo> 
     System.out.println(((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]); //output: class Foo 
    } 

    public static void main(String[] args) { 
     new ChildClass(); 
    } 

} 

子类

import java.lang.reflect.ParameterizedType; 


public class ChildClass extends GenericClass<Foo> { 

    public ChildClass() { 
     System.out.println(((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]); //output: class Foo 
    } 

} 
+0

感谢您的回复。 – 2012-02-23 16:59:07

3

在运行时无法从您的类BaseLabel中找到此信息,因为它不知道它已通过实例化的通用类型。这是因为Java对泛型使用了类型擦除 - 泛型参数不是运行时伪像。

+0

@matthewSpleep非常感谢您的解释。如果我从抽象BaseClass的构造函数中调用this.getClass.getSimpleName()。它正在打印ChildClass。你能告诉我为什么这样做吗?是因为我正在实例化ChildClass,所以它指向ChildClass的对象。 – 2012-02-23 17:02:56

+0

动态解析Java方法(使用对象的运行时类)getClass()调用仍然知道该对象最终是一个“ChildLabel”,即使代码是在“BaseLabel”中调用的。 – matthewSpleep 2012-02-23 18:14:05

0
((Class<?>)((ParameterizedType) clazz.getGenericSuperclass()).getActualTypeArguments()[0]).getName(); 

做的工作。