在下面的代码示例中,<T>
方法的返回类型之前的泛型类型声明get
是什么意思?
public interface Listener<T, R> {
<T> Listener<T, R> get();
}
我在Listener
的类声明中了解了它的含义,但我没有找到以这种方式使用<T>
作为方法的实际示例。
答案 0 :(得分:2)
这是方法范围内的参数化类型。它仅在get()
方法的范围内定义,并且隐藏在T
类中声明的Listener
。
隐藏类型是要避免的事情,在泛型类中定义方法范围的参数化类型通常是有问题的。
我想知道该参数在那个地方的作用。
此处T
是方法的客户端推断的类型。
但是由于此T
与类中声明的T
不同,因此它可以是不同的类型。
如果要将通用类的T
转换为客户端指定的另一种类型,则可能很有意义。
例如,假设实现:
public class MyListener implements Listener<String, Integer>{
@Override
public <T> Listener<T, Integer> get() {
return convert to T and return a new instance of Listener...;
}
}
所以您可以写:
MyListener myListener = new MyListener();
Listener<Float, Integer> listener = myListener.get();
请注意,返回的Listener
和MyListener
不是兼容类型。
我要补充一点,您的接口实际上是一个功能接口,因为它声明了一个抽象实例方法。
使用泛型方法不允许将函数接口与lambdas主体一起使用,而只能与方法引用一起使用。
例如,这些无法编译:
Listener<String, Integer> invalidListener = () -> new MyListener<String, Integer>();
Listener<String, Integer> invalidListener2 = () -> new MyListener<>();
方法参考将编译:
Listener<String, Integer> validListener = MyListener::new;
答案 1 :(得分:2)
这是方法特定的参数化类型,但是...接口中已经定义了T
和R
参数,因此应避免这种情况,因为它从接口隐藏了已定义的参数。
正确的用法示例是接口仅定义参数R
的情况:
public interface Listener<R> {
<T> Listener<R> get(T t);
}
但是,即使这种用法也值得怀疑。这个例子很清楚-接口使用参数R
,并且只有其方法另外使用T
。没有这种<T>
特征的另一种方法将无法使用T
。