Java 泛型
需要搞个服务从 Excel 里读取数据转化为实体类,再转发到其他平台。读取的数据有车辆数据和电池数据,就想着一个接口搞个泛型,读取不同数据的服务按照类型实现接口就行了,但一开始没整明白。
List<?> 和 List <T>
List<?>
List<?>
是一个无限定通配符类型的列表,也被称为“类型通配符列表”,它可以包含任何类型的元素。但因为它的类型未知,无法在编译时进行类型检查。
具体使用的例子如下,首先是服务的接口,使用 List<?>
,表明这个接口的实现类可以按需要返回任意类型的列表:
public interface IDataReadService {
List<?> DataListRead(InputStream inputStream, String filename);
}
然后是这个接口的实现类,只需要重写方法并按需要写明返回的类型即可:
@Service
public class TestService implements IDataReadService{
@Override
public List<TestEntity> DataListRead(InputStream inputStream, String filename) {
List<TestEntity> testList = new ArrayList<>();
// TODO
return testList;
}
}
最初想到的方式,误打误撞写的也没什么问题,也算是实现了需求。
List <T>
List<T>
是一个泛型类,其中的<T>
是一个类型参数,可以被替换为任何有效的Java类型,例如String
或Integer
。在编译时,编译器会对类型参数进行类型检查,并确保只有 T 类型的对象可以添加到该列表中。区别在于,
List<T>
可以容纳任何指定类型的元素,并且在编译时可以进行类型检查,而List<?>
是一个未知类型的列表,因此无法进行编译时类型检查。 因此,在编写泛型代码时,应该尽可能使用List<T>
来获得更好的类型安全性和可读性。 但是,在某些情况下,如果你不关心列表中的元素类型,或者你需要在代码中接受任何类型的列表,则可以使用List<?>
。
就我的理解来看,它们的区别在于:List<?>
在定义后就不管后面怎么用了,反正它接受一切类;但 List<T>
在定义后,后面使用时需要指定具体的 T 类型。
使用 List<T>
改造上面的例子,首先是服务的接口:
public interface IDataReadService<T> {
List <T> DataListRead(InputStream inputStream, String filename);
}
此处的接口定义就要加上 <T>
,在使用时指定这个 T 类型,则其中的 T 类型都会被指定,实现类如下:
@Service
public class TestService implements IDataReadService<TestEntity>{
@Override
public List<TestEntity> DataListRead(InputStream inputStream, String filename) {
List<TestEntity> testList = new ArrayList<>();
// TODO
return testList;
}
}
相当于这个 T 是一个占位符,使用到的时候给出具体的类型,这样就可以进行类型检查了,所以才比直接用 <?>
更安全吧。
泛型的上下界
<?>
虽然是无限制类型通配符,但它也可以对接收的类型做出限制,如:
<?> // 无限制通配符
<? extends T> // 声明了类型的上界,即接收的类型可以是所指定的类型,或者是此类型的子类
<? super T> // 声明了类型的下界,即接收的类型可以是所指定的类型,或者是此类型的父类
上界
class Info<T extends Number>{ // 要求传入的类型必须是 Number 或其子类
private T var ; // 类型为传入的类型
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){
return this.var.toString() ;
}
}
public class TestExtends{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>(); // 声明Integer的泛型对象
System.out.println(i1);
}
}
下界
class Info<T>{
private T var ; // 类型为传入的类型
public void setVar(T var){
this.var = var ;
}
public T getVar(){
return this.var ;
}
public String toString(){
return this.var.toString() ;
}
}
public class TestSuper{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 声明String的泛型对象
Info<Object> i2 = new Info<Object>() ; // 声明Object的泛型对象
i1.setVar("hello") ;
i2.setVar(new Object()) ;
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<? super String> temp){ // 要求传入的必须是 String 或其父类,String 的父类只有 Object
System.out.println(temp) ;
}
}
标签:Java,String,List,var,类型,泛型,public From: https://www.cnblogs.com/qiyuanc/p/Back13.html部分参考:Java 全栈知识