首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

请问关于得到泛型的class

2012-11-07 
请教关于得到泛型的class在发帖之前,一直在考虑。该不该发。查了查我的问题。也没有找到一个解决方案。所以,还

请教关于得到泛型的class
在发帖之前,一直在考虑。该不该发。查了查我的问题。也没有找到一个解决方案。所以,还是来发帖了。就发在新手帖吧。也许真的只是一个新手的问题。


先描述一下问题。有这个一个类:



查找原因。发现,java中的泛型采用擦拭法。无法得到自己本身的泛型。而调用getGenericSuperclass()方法得到的是父类的泛型。
所以,再次修改代码:

这下郁闷了。按道理说,这个是没有问题的。
于是我再次修改代码。把15行的注释打开,把14行注释掉。于是,代码如下:
public class Test2<T>{Class<T> clazz;@SuppressWarnings("unchecked")public Test2(Class<T> clazz){this.clazz = clazz;System.out.println(clazz);}public static void main(String[] args){Test2<Integer> t = new Test2<Integer>(Integer.class);}}

3 楼 RyanPoy 2008-07-18   <p>总结。 <br/>对于解决方法1,要注意这样几点。 <br/>1). 只能取得父类的T.class,而且,要写一个子类,且子类在继承父类的时候,就要把类型给确定下来。即:?</p>
<pre name='code' class='java'>public class Test extends Father&lt;Integer&gt;
{
}</pre>
<p>? <br/><br/>这样的话,其实Test在定义的时候就已经确定了类型了。 <br/><br/>2). 这种方式不灵活,非得一个父类,一个子类。那么如果有一个Dao</p>
<pre name='code' class='java'>public class Dao&lt;T&gt;
{
Class clazz;

public Dao()
{
clazz = (Class) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
}</pre>
<p>?<br/><br/>如果要针对具体类型的时候,那么就得一个子类</p>
<pre name='code' class='java'>public class UserDao extends Dao
{
}</pre>
<p>?</p>
<p>同理,如果要操作多个对象,那么就有多个子类。这样,很冗余。 <br/><br/>对于解决方式2, <br/>1). 只需要一个类。而能解决所有的问题。</p>
<pre name='code' class='java'>public class Test &lt;T&gt;
{
} </pre>
<p>?<br/><br/>2). 这个类需要一个带参数的构造。且这个参数就是泛型的class。也就是说,这个泛型的class是由外面传进去的。</p>
<pre name='code' class='java'>public class Test &lt;T&gt;
{
Class clazz;

public Test(Class clazz)
{
this.clazz = clazz;
}
}</pre>
<p>?<br/><br/><br/>3). 这种方式没有冗余。同样,以一个Dao来举例。</p>
<pre name='code' class='java'>public class Dao&lt;T&gt;
{
Class clazz;

public Dao(Class clazz)
{
this.clazz = clazz;
}
}</pre>
<p>?<br/>这样,如果有一个UserDao,我们只需要。</p>
<pre name='code' class='java'>Dao userDao = new Dao(User.class); </pre>
<p>?<br/><br/>4). 这种方式对应于c++中的template更为接近。 </p>
<p>??</p>
<p>?c++中:</p>
<pre name='code' class='cpp'>template &lt;class T&gt;
class Dao
{
public:
    Dao()    {}
    ~Dao()  {}
};

int main(int argc, char* argv[])
{
     Dao* dao = new Dao;
     delete dao;

     return 0;
} </pre>
<p>?<br/>java中:</p>
<pre name='code' class='java'>public class Dao&lt;T&gt;
{
Class clazz;

public Dao(Class clazz)
{
this.clazz = clazz;
}

public static void main(String[] args)
{
Dao dao = new Dao(User.class);
}
}</pre>
<p>?<br/><br/>两者唯一的区别在于。 <br/>1). c++代码中的构造方法可以不用参数,是一个默认构造就可以了。至于具体的是什么类型的参数。这个是在编译器编译成2进制文件时自动转化。 <br/><br/>2). java代码中的构造方法,需要传递一个Class,这个Class就是T的Class。表面上看,好像这样子不合理。但是实际上想想,也没有不合理的地方。因为</p>
<pre name='code' class='java'>Dao&lt;User&gt; dao = ...
</pre>
<p>?</p>
<p>这个地方的时候,你就已经确定了是对User进行操作。那构造方法中传递一个User.Class,又有何不可呢? <br/><br/>综上,采用2种方式中的任意一种都可以。不过,我更加喜欢第2种。 <br/><br/><br/></p>
<p>?</p> 4 楼 dajianshi 2008-09-26   不是不行,只是有点Ugly 5 楼 davidcen 2008-12-22   public abstract class BaseDAOImpl<T> extends JpaDaoSupport implements
IBaseDao<T> {

protected String className = "";


@SuppressWarnings("unchecked")
protected BaseDAOImpl() {
TypeVariable[] typeVariables = getClass().getTypeParameters();
if (typeVariables != null && typeVariables.length > 0) {
className = typeVariables[0].getName();
}
}
...
} 6 楼 sigon 2008-12-24   也正在查这个问题,楼主这篇文章帮助很大,谢谢 7 楼 jiajia11 2012-09-27   其实第二种方法我觉得不是泛型的应用,你把<T>去掉也是可以传进去参数的。
在DAO的应用中为了抽象出共同代码是应该有父类的,子类对应不同的DAO实现类。
所以第一种实现方法是对的。(个人理解)

热点排行