Java泛型调用返回<T extends>对象的方法

Bic*_*ick 2 java java-8

我有一个名为TResult的课程

public class TResult<T extends MyEntity>  {

    public List<T> getEntityList() {
        return entityList;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在其他一些返回它的类中有一个静态方法

public static TResult getAllEntities(final Class clazz, RouteFilter filter ){
}
Run Code Online (Sandbox Code Playgroud)

现在,当我调用getAllEntities时,我需要将其转换为MyEntity,否则我会收到警告(未经检查的分配).我尝试更改方法签名,它只适用于

public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class clazz, RouteFilter filter) {}
Run Code Online (Sandbox Code Playgroud)

为什么我必须指出T在已经在TResult类签名中定义时在getAllEntities方法中扩展了APIBaseEntity?

TResult<APIBaseEntity> allEntities = GeneralCRUD.getAllEntities(APIAccount.class, filter);
Run Code Online (Sandbox Code Playgroud)

Jof*_*rey 6

首先,你不应该使用原始类型*,这将有助于你理解你在使用泛型类时所做的事情.

问自己这些问题:什么课程clazz?什么样的TResult要退?提供的类是否应该定义类型参数TResult

如果对最后一个问题的答案是肯定的,那么你可能正在寻找这样的声明:

public static <T extends APIBaseEntity> TResult<T> getAllEntities(final Class<T> clazz, RouteFilter filter) {
    //...
}
Run Code Online (Sandbox Code Playgroud)

这基本上强制返回TResult<T>的类型T与提供clazz的类型相同:方法的类型参数.这也消除了转换为所需返回类型的负担,因为编译器现在已经知道了.

为什么我必须指出T在已经在TResult类签名中定义时在getAllEntities方法中扩展了APIBaseEntity?

如果你写public <T> TResult<T> myMethod(),T是你的方法的通用类型,但根本没有约束,所以它可以是任何东西.TResult<T>不作为方法的类型参数的约束.你必须自己明确地约束它,因为你甚至可以比TResult类更多地限制它(例如使用子类型APIBaseEntity).

如果你不限制你的方法的类型参数,你会得到一个编译错误/警告(不记得从我的头脑中),因为它不适合TResult类型参数声明.


*注意: 原始类型是没有类型参数引用的泛型类型,例如 Class or TResult,而不是 Class<T> TResult<T>.