我开始使用Java泛型。我有一个Parameter接口及其ParameterImpl具体类。 T将是Float,Long,Integer或String。
public interface Parameter<T extends Comparable<T>> {}
public class ParameterImpl<T extends Comparable<T>> implements Parameter<T> {}
在其他课程中,请说public class A
和public class B
:
类型参数的类变量可以声明为:Parameter parameter
或Parameter<?> parameter
但不能Parameter <T> parameter
。
//warning, should be parameterized
Parameter p;
//no warning
Parameter<?> p2;
//error
Parameter<T> p3;
//warning, should be parameterized
Map<String, Parameter> pMap;
//no warning
Map<String, Parameter<?>> pMap2;
//error
Map<String, Parameter<T>> pMap3;
那么在被问到时我应该到处使用通配符吗?或者只是忽略警告并使用非参数化版本?
这些方法有三种选择:
public <T extends Comparable<T>> Parameter<T> getParameter2(Map<String, Parameter<T>> map, String key) { return null; }
public Parameter <?> getParameter (Map<String, Parameter<?>> map, String key){ return null; }
public Parameter getParameter3(Map<String, Parameter> map, String key) { return null; }
与类变量情况类似,最后一个有关于参数化的警告。我应该走哪条路?
答案 0 :(得分:0)
您应该声明具体类型,例如:
Parameter<Long> p2 = ...;
您的方法将是:
public Parameter<T> getParameter3(Map<String, Parameter<T>> map, String key) { return null; }
或者如果您需要更具体的版本
public Parameter<Long> getParameter3(Map<String, Parameter<Long>> map, String key) { return null; }
使用通配符然后它可以是任何类型,即当您编写非常通用的函数或声明非常通用的参数时。您还可以使用有界通配符来强制您继承Number
,例如:
Paremeter<? extends Number> numberedParameter;
答案 1 :(得分:0)
您的类型Parameter
是通用的。
此
Parameter p;
使用Parameter
作为原始类型。 Avoid using it.
此
//no warning
Parameter<?> p2;
正在使用Parameter
,其类型参数为?
,即通配符。您可以将任何类型Parameter
的值分配给变量p2
,无论其参数化如何。
此
//error
Parameter<T> p3;
正在尝试使用名为T
的类型作为Parameter
的类型参数。如果此类型不存在或不在范围内,则会发生编译器错误。这似乎正在发生。
那么在被问到时我应该到处使用通配符吗?
不,使用相应的类型参数。这取决于你想做什么。