首页 > 编程语言 >Java 泛型

Java 泛型

时间:2023-04-24 15:24:07浏览次数:41  
标签:Java String List var 类型 泛型 public

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 全栈知识

标签:Java,String,List,var,类型,泛型,public
From: https://www.cnblogs.com/qiyuanc/p/Back13.html

相关文章

  • Java的final修饰符
    final实例域可以将实例域定义为final。对于final域来说,构建对象时必须初始化final实例域,构造对象之后就不允许改变final实例域的值了。也就是说,必须确保在每一个构造器执行之后,final实例域的值被设置,并且在后面的操作中,不能够再对final实例域进行修改。例如,可以将Em......
  • javaIO之随机读写
    javaIO包提供了很多可以读写文件的类,但是如果想在文件的指定位置读写,就需要使用RandomAccessFilepublicclassApp{publicstaticvoidmain(String[]args)throwsIOException{{Strings1="ggg\n";Strings2="ggg,hhh\n";......
  • java中排序的正确用法
    publicclassTest{publicstaticvoidmain(String[]args){sort();}publicstaticvoidsort(){List<Integer>list=newArrayList();//降序hitRule.sort((o1,o2)->o2.compareTo(o1));//升序......
  • JAVA学习笔记随记1(类与对象)
    首先说明,这是为了学习java而做的笔记,所以记起来可能杂乱无章,无所谓了,刚开始学习都是这样的。。。首先小结下String的知识点String可以直接声明并赋初值并可以修改,例如:Stringabc="a";abc="b";其次字符串之间的连接用'+',只要出现字符串和其他数据类型之间用'+'连接,那么该......
  • java token自定义实现
    importcom.example.newsmanager.model.Token;importjavax.servlet.http.Cookie;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;publicclassTokenUtil{publicstaticfinalStringTOKEN_NAME="token&......
  • JavaScript 实现伽马算法
    伽马函数是数学中的一个非常重要的函数,它在统计学、物理学等领域有广泛的应用,其中最重要的应用就在概率统计和计算机科学中。接下来,我们来介绍如何使用JavaScript实现伽马算法。递归实现functiongamma(x){if(x===1){return1;}else{return(x-1)......
  • JAVA流程控制
    Java流程控制一、Scanner对象next():一定要读取到有效字符后才可以结束输入对输入有效字符之前遇到的空白,next()方法会自动将其去掉只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符next()不能得到带有空格的字符串nextLine():以Enter为结束符也就是说ne......
  • 前端进化笔记-JavaScript(一)
    简介:实现:三部分ecmascript语言核心DOM文档对象模型BOM浏览器对象模型DOM:用于html的应用程序接口(API),把整个页面映射成一个多层节点结构。例如:<html> <head> <title>samplepage</title> </head> <body> <p>helloworld</p> </body></html>DOM......
  • Java-Day-15( 异常 )
    Java-Day-15异常引出异常(Exception)如:零成分母时,会抛出ArithmeticException异常,然后程序就会崩溃退出,下面的代码也就不执行了但这种不出现致命错误就使得系统崩溃就不合理了所以设计者提供了异常处理机制来解决此问题解决方式—异常捕获如果程序员认为一段......
  • JavaScript 基础问答
      JavaScript数据类型有哪几种?  一共有五种:number、string、object、boolean、undefined.其中最后一个是定义变量后没有赋值介绍隐式类型转换字符串+数字=字符串;字符串-数字=数字;+数字字符串=数字null经过数字转换之后会变为0undefined经过数字转换之后会变为NaN......