Java泛型接口返回泛型。

6

我从教程中找到了这段代码,猜测方法getUriBase的返回类型为String,但不清楚部分<T extends IEntity>在方法中扮演什么角色,为什么放在开头?

public interface IUriMapper {
    <T extends IEntity> String getUriBase(final Class<T> clazz);
}

1
在这种情况下,它基本上等同于 String getUriBase(Class<? extends IEntity> clazz); - shmosel
2个回答

4
这是创建泛型方法的规则。
泛型方法的语法包括在尖括号中的类型参数,并出现在方法返回类型之前。对于静态泛型方法,类型参数部分必须出现在方法返回类型之前。
如果在返回类型String之前看到then,则定义了类型参数T<T extends IEntity>表示您正在创建有界类型参数,其中您告诉编译器T应该是的子类。请注意,您需要在方法之前定义<T extends IEntity>(这就是所谓的“泛型方法”,更多信息即将到来...)因为您的接口不是泛型类型。假设您的接口如下,则无需定义T类型参数,因为编译器会知道T类型参数是什么。
public interface IUriMapper<T extends IEntity> {
    String getUriBase(final Class<T> clazz);
}

因此,基本上泛型方法是有用的(或者换句话说适用于某些情况),当您想要定义自己的类型时。考虑下面的例子,在这个例子中,您的泛型类型(接口“ IUriMapper”)定义了类型参数“ T”,但是对于getUriBase方法,您正在创建一个新的类型“E”。
public interface IUriMapper<T extends IEntity> {
    <E extends Number> String getUriBase(final Class<E> clazz);
}

这份Oracle文档是学习泛型的最佳资源。


2

泛型类型

类型参数部分由尖括号(<>)包围,紧跟在类名后面。它指定了类型参数(也称为类型变量)T1、T2、...和Tn。

public class Box {
    private Object object;

    public void set(Object object) { this.object = object; }
    public Object get() { return object; }
}

要将Box类更新为使用泛型,您需要通过将代码“public class Box”更改为“public class Box”创建一个泛型类型声明。这引入了类型变量T,它可以在类内部的任何地方使用。
/**
 * Generic version of the Box class.
 * @param <T> the type of the value being boxed
 */
public class Box<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

来源:https://docs.oracle.com/javase/tutorial/java/generics/types.html


有限制的类型参数:

有时候你可能想要限制参数化类型中可以使用的类型。例如,一个操作数字的方法只想接受 Number 类型或其子类的实例。这就是有限制的类型参数的作用。

public class Box<T> {

    private T t;          

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    public <U extends Number> void inspect(U u){
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.set(new Integer(10));
        integerBox.inspect("some text"); // error: this is still String!
    }
}

来源:https://docs.oracle.com/javase/tutorial/java/generics/bounded.html


1
你能回答一下这个问题中它如何适配接口方法的情况吗? - Downhillski
在您的问题中,该方法所期望的参数必须是IEntity的子类。这意味着IEntity中必须有一些方法需要泛型对象具备。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接