*代码仅为示例,不从实际意义出发设计示例类
public class BaseService<T, R> {
private T entityA;
private R entityB;
public T getEntityA() {
return this.entityA;
}
public void setEntityA(T entityA) {
this.entityA = entityA;
}
public R getEntityB() {
return this.entityB;
}
public void setEntityB(R entityB) {
this.entityB = entityB;
}
}
T、R为类型参数,既然称之为参数那么就有必然要有【设定参数值】的时候。
对于java泛型类的类型参数,什么时候指定&如何指定【设定参数值】呢?
只要使用/引用java泛型类就可以明确类型参数的值即明确类型!
1、继承java泛型类
public class SalesOrderService extends BaseService {
// SalesOrderService 没有明确类型参数T,R的数据类型,此时编译器会警告提示
// BaseService is a raw type. References to generic type BaseService<T,R> should be parameterized
}
如果你决定不明确参数类型,那么对于SalesOrderService来说,它继承下来的getEntityA、setEntityA、getEntityB、setEntityB的数据类型均为BaseService的原始类型即类型擦除后的数据类型Object。
剖析一下继承时的几种设定类型参数的场景:
public class SalesOrderService extends BaseService<String> {
// 不能对多个类型参数,只做部分指定。会报编译错误!
}
public class SalesOrderService extends BaseService<String, R> {
// 这个R的意思也不是说保持BaseService的类型参数R不变。
// R会被认定为一个新的类型参数,但是设置的位置又不对。SalesOrderService出现的类型参数只能在SalesOrderService类名的后面
}
public class SalesOrderService<R> extends BaseService<String, R> {
// 编译不会有问题,但是此时的R代表的是SalesOrderService新定义的类型参数,用它来指定了BaseService的第二个类型变量而已。
}
==============================================================
public class SalesOrderService<R extends TypeNew> extends BaseService<String, R> {
// 编译不会有问题,但是此时的R代表的是SalesOrderService新定义的类型参数,用它来指定了BaseService的第二个类型变量而已。
}
class TypeNew{
}
这种实现方式就代表着BaseService 的两个类型参数均被指定,一个String,一个R extends TypeNew,那么在使用SalesOrderService时再去指定R即可。如果不指定那么
SalesOrderService的原始类型就是String和TypeNew。
2、实例化java泛型类(包含了定义和实例化)
// 此时编译提示警告:BaseService<T,R> should be parameterized
// 如果执意不设定类型参数,那么就jvm会按照BaseService<Object,Object>来处理
BaseService baseService = new BaseService();
// 同理,不允许部分参数化
BaseService<String> baseService = new BaseService();
// 因为类型参数只在方法/类上定义,so在实例化时不能再定义新的类型参数,编译错误
BaseService<String, X> baseService = new BaseService<String, X>();
// 这才是正解,其中定义时明确了类型BaseService<String, Integer> baseService,
同时实例化时也明确了类型new BaseService<String, Integer>
BaseService<String, Integer> baseService = new BaseService<String, Integer>();
类的引用也就这两种形式了吧。你还能想到其他的吗?欢迎和我探讨。
希望读完能让你以后再使用泛型类时没有疑问,不靠猜!哈哈哈哈