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当参数的主要内容,如果未能解决你的问题,请参考以下文章

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

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

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

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

where T : class泛型类型约束

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