Java 如何获取泛型T的T.class当参数

Posted 请叫我大师兄_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 如何获取泛型T的T.class当参数相关的知识,希望对你有一定的参考价值。

先说需求,本意是想在父类里面实现一些最基础的方法,然后子类只需要简单的继承,然后就可以有大部分方法可以使用了。我这儿实际就是一个crud的接口,然后给这个接口来个base实现,除非特殊需求,简单继承这个base实现就能实现model的crud。但是呢,find all方法内部需要一个使用另外一个方法,这个方法必须的传入T.class 当参数。看接口和他的base实现

public interface CrudRepository<T> 
    Iterable<T> findAll();


public class BaseImpl<T> implements CrudRepository<T> 

    @Override
    public Iterable<T> findAll() 
        Class<T> c = getTClass();
        System.out.println(c);

        common(c);
        return null;
    

    public Iterable<T> findAll(Class<T> c) 
        System.out.println(c);

        common(c);
        return null;
    

    /**
     * 通用的方法使用泛型的class去干一些事情。
     *
     * @param c 泛型类
     */
    private void common(Class<T> c) 

    

    /**
     * 获取 T.class
     *
     * @return T.class
     */
    public Class<T> getTClass() 
        return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    

对应的有2个model要实现数据库的crud,Phone 和Computer,具体如下。

@Data
public class Phone 
    private static final long serialVersionUID = 1L;
    private String name;
    private Long price;
    private Long updateDate;

public class PhoneRepository extends BaseImpl<Phone> 


@Data
public class Computer 
    private static final long serialVersionUID = 1L;
    private String name;
    private Long price;
    private Long updateDate;

public class ComputerRepository extends BaseImpl<Computer> 

实际测试类,如下:

public class T 
    private final PhoneRepository phoneRepository = new PhoneRepository();
    private final ComputerRepository computerRepository = new ComputerRepository();
    @Test
    public void t() 
        Iterable<Phone> phones = phoneRepository.findAll();
        phones = phoneRepository.findAll(Phone.class);
        System.out.println();

        Iterable<Computer> computers = computerRepository.findAll();
        computers = computerRepository.findAll(Computer.class);
        System.out.println();
    

上述代码中,提供了2种方案,

1,硬刚,我就要使用T.class,这个方法还不带参数的,就是我上面base实现类里面的无参数的 findAll()方法,里面提供了获取T.class的方法,获取后,当参数再调用其他的方法。

2,绕一下,把T.class当参数传进去。就是findAll(Class<T> c),这也能实现,稍微绕了点,

1的优点就是直接实现接口,不改接口,不影响已经存在的调用,

2的缺点就是没实现接口,涉及到使用接口提供的findAll()的地方,都得修改,影响范围广

以上是关于Java 如何获取泛型T的T.class当参数的主要内容,如果未能解决你的问题,请参考以下文章

C#如何将类型Type作为泛型T的参数T传递

在java中,使用泛型,比如说T,但是T.class就要报错。我想获取T的class对象怎样获取啊。

Java:泛型参数上带有.class的泛型方法[重复]

获取抽象超类上泛型类型参数的实际类型

where T : class泛型类型约束

泛型中Where T:Class和Where T:new()的使用与区别