Java——泛型(概念理解+应用举例)

简介: Java——泛型(概念理解+应用举例)

1.泛型的概念


泛型是一种末知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型。泛型也可以看成是一个变量用来接收数据类型。E eElement元素,T tType类型。

集合中可以存储任意类型的对象元素,但是当把一个对象存入集合后,集合会忘记这个对象的类型,将该对象从集合中取出时,这个对象的编译类型就统一变成了 Object 类型。

换句话说,在程序中无法确定一个集合中的元素到底是什么类型,那么在取出元素时,如果进行强制类型转换就很容易出错。

 

2.是否使用泛型的对比 


2.1 不使用泛型 

创建集合对象,不使用泛型。     好处:集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据。

                                              弊端:不安全,会引发异常。

2.1.1 好处 

import java.util.*;
public class GenericDemo01 {
  public static void main(String[] args) {
    ArrayList arraylist=new ArrayList();//集合不使用泛型
    //向集合中添加数据,用于测试,这里添加了String类型和int类型的数据
    arraylist.add("ABC");
    arraylist.add(123);
    Iterator iterator=arraylist.iterator();
    while(iterator.hasNext()) {//取出的元素的类型默认是Object类型
      System.out.print(iterator.next() + " ");
    }
  }
}

2.1.2 弊端

import java.util.*;
public class GenericDemo02 {
  public static void main(String[] args) {
    ArrayList arraylist=new ArrayList();
    arraylist.add("ABC");
    arraylist.add(123);
    Iterator iterator=arraylist.iterator();
    while(iterator.hasNext()) {
      //取出的数据,默认是Object类型
      Object obj=iterator.next();
      /*假如想使用String类特有的length()方法来获取字符串的长度,是不可以的
                          需要将Object类型向下转型为String类型才能使用它的特有方法
                          但是集合里面还有数据类型为Integer的数据,所以不能进行向下转型为String类型,
                          如果强行转换,那么在运行时会抛出ClassCastException异常*/
      String str=(String)obj;
      System.out.println("该元素的长度为:" + str.length());
    }
  }
}


2.2 使用泛型

2.2.1 好处及弊端 

import java.util.*;
public class GenericDemo03 {
  public static void main(String[] args) {
    //使用泛型限定数据类型为String类的字符串
    ArrayList<String> arraylist=new ArrayList<String>();
    arraylist.add("ABC");
    /*假如添加的数据的类型不是String类型
      arrayList.add(123);这条语句会抛出错误:
      方法java.util.Collection.add(java.lang.String)不适用*/
    Iterator<String> iterator=arraylist.iterator();
    while(iterator.hasNext()) {
      String str=iterator.next();
      System.out.print("该元素为:" + str + "\n" + 
                "长度为:" + str.length());
    }
  }
}


3.定义和使用含有泛型的类


3.1 说明 


泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。

定义和使用含有泛型的类的格式如下:修饰符 class 类名称<代表泛型的变量类型> { . . . }

修饰符 class 类名称<代表泛型的变量类型> { . . . }

修饰符 class 类名称<代表泛型的变量类型> { . . . }


3.2 举例 


class GenericClass<E> {
  private E name;
  public void setName(E name) {
    this.name=name;
  }
  public E getName() {
    return this.name;
  }
}
public class GenericDemo04 {
  public static void main(String[] args) {
    //使用泛型,限定该类的数据类型为String类
    GenericClass<String> name1=new GenericClass<String>();
    name1.setName("使用泛型:这里只能添加指定类型的数据!");
    String str1=name1.getName();
    System.out.println(str1);
    //不使用泛型,该类的数据类型默认为Object类
    GenericClass name2=new GenericClass();
    name2.setName("不使用泛型:这里能添加不同类型的数据!");
    Object obj1=name2.getName();
    System.out.println(obj1);
  }
}

 

4.定义和使用含有泛型的方法 


4.1 说明 

定义含有泛型的方法:泛型定义在方法的修饰符和返回值类型之间。

格式:修饰符 <泛型> 返回值类型方法名(参数列表(使用泛型)){ 方法体 };

含有泛型的方法,在调用方法的时候确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型

4.2 举例 

class GenericMethod {
  public <W> String method1(W w) {
    return "一个使用泛型的普通方法:" + w;
  }
  public static <Z> String method2(Z z) {
    return "一个使用泛型的静态方法:" + z;
  }
}
public class GenericDemo05 {
  public static void main(String[] args) {
    GenericMethod use=new GenericMethod();//创建一个类对象
    /*调用包含泛型的普通方法
      对应的普通方法为:public <Integer> String method1(Integer 666),w=666*/
    System.out.println(use.method1(666));
    //对应的普通方法为:public <String> String method1(String LOVE),w=LOVE
    System.out.println(use.method1("LOVE"));
    /*调用包含泛型的静态方法
      虽然可以通过对象来调用,但还是推荐使用类进行调用
      对应的静态方法为:public static <String> String method2(String ABC),z=ABC*/
    System.out.println(GenericMethod.method2("ABC"));
    //对应的静态方法为:public static <Double> String method2(Double 521.1314),z=521.1314
    System.out.println(GenericMethod.method2("521.1314"));
  }
}

5.定义和使用含有泛型的接口


5.1 说明 


含有泛型的接口第一种使用方式:通过定义接口的实现类,实现接口,指定接口的泛型。

含有泛型的接口第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走。就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型。


5.2 举例 


5.2.1 含有泛型的接口第一种使用方式

//博主在这里有点懒,将接口和实现接口的类都写在了一个.java源文件中
//推荐大家将接口和其他的类都单独的写在一个.java源文件中
interface GenericInterface<I> {
  public void method(I i);//接口中的一个抽象方法
}
class Genericing implements GenericInterface<String> {
  public void method(String s) {
    System.out.println("通过定义接口的实现类,实现接口,指定接口的泛型\n" + 
              "这个方法传入指定类型参数是:" + s);
  }
}
public class GenericDemo06 {
  public static void main(String[] args) {
    Genericing generic=new Genericing();
    generic.method("定义和使用接口的第一种方式!");
  }
}

5.2.2 含有泛型的接口第二种使用方式

interface GenericInterface01<I> {
  public void method(I i);
}
class Genericing01<I> implements GenericInterface01<I> {
  public void method(I i) {
    System.out.println("接口使用什么泛型,实现类就使用什么泛型,类跟着接口走\n" + 
              "创建对象的时候传入指定类型参数是:" + i);
  }
}
public class GenericDemo07 {
  public static void main(String[] args) {
    Genericing01 generic=new Genericing01();
    generic.method(2020);
  }
}


6.泛型通配符


6.1 说明 


通配符基本使用泛型的通配:不知道使用什么类型来接收的时候,此时可以使用 ?? 表示未知通配符,即:表示任意的数据类型。

使用方式:不能创建对象使用,只能作为方法的参数使用。

注意:一但使用泛型的通配符,那么,只能使用Object类中的共性方法,集合中元素的自身方法无法使用。 


6.2 举例 


import java.util.*;
class IteratorArrayList {
  //由于不确定接收的ArrayList集合中的元素是什么类型,所以使用泛型通配符 ?
  //array1的元素为Integer类型,array2的元素为String类型
  public static void printing(ArrayList<?> array1) {
    Iterator<?> iterator=array1.iterator();
    while(iterator.hasNext()) {
      Object obj=iterator.next();//next()方法取出的元素类型是Object,可以接收任意的数据类型
      System.out.print(obj + " ");
    }
  }
}
public class GenericDemo08 {
  public static void main(String[] args) {
    //array1集合限定数据类型为Integer
    ArrayList<Integer> array1=new ArrayList<Integer>();
    array1.add(111);
    array1.add(222);
    array1.add(333);
    array1.add(444);
    array1.add(555);
    System.out.print("遍历Integer数据类型的array1集合:");
    IteratorArrayList.printing(array1);
    System.out.println();
    System.out.println("====================================");
    //array2集合限定数据类型为String
    ArrayList<String> array2=new ArrayList<String>();
    array2.add("一号元素");
    array2.add("二号元素");
    array2.add("三号元素");
    array2.add("四号元素");
    array2.add("五号元素");
    System.out.print("遍历String数据类型的array2集合:");
    IteratorArrayList.printing(array2);
  }
}


那么,以上就是我对 Java 泛型的理解,欢迎大家留言评论,一起学习,共同进步!!!😄😄😄 

相关文章
|
1月前
|
人工智能 算法 Java
Java与AI驱动区块链:构建智能合约与去中心化AI应用
区块链技术和人工智能的融合正在开创去中心化智能应用的新纪元。本文深入探讨如何使用Java构建AI驱动的区块链应用,涵盖智能合约开发、去中心化AI模型训练与推理、数据隐私保护以及通证经济激励等核心主题。我们将完整展示从区块链基础集成、智能合约编写、AI模型上链到去中心化应用(DApp)开发的全流程,为构建下一代可信、透明的智能去中心化系统提供完整技术方案。
227 3
|
1月前
|
Java 编译器 Go
【Java】(5)方法的概念、方法的调用、方法重载、构造方法的创建
Java方法是语句的集合,它们在一起执行一个功能。方法是解决一类问题的步骤的有序组合方法包含于类或对象中方法在程序中被创建,在其他地方被引用方法的优点使程序变得更简短而清晰。有利于程序维护。可以提高程序开发的效率。提高了代码的重用性。方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。这种就属于驼峰写法下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。
196 4
|
1月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
121 8
|
2月前
|
安全 Java
Java之泛型使用教程
Java之泛型使用教程
234 10
|
2月前
|
人工智能 Java API
Java与大模型集成实战:构建智能Java应用的新范式
随着大型语言模型(LLM)的API化,将其强大的自然语言处理能力集成到现有Java应用中已成为提升应用智能水平的关键路径。本文旨在为Java开发者提供一份实用的集成指南。我们将深入探讨如何使用Spring Boot 3框架,通过HTTP客户端与OpenAI GPT(或兼容API)进行高效、安全的交互。内容涵盖项目依赖配置、异步非阻塞的API调用、请求与响应的结构化处理、异常管理以及一些面向生产环境的最佳实践,并附带完整的代码示例,助您快速将AI能力融入Java生态。
462 12
|
2月前
|
安全 Java API
Java SE 与 Java EE 区别解析及应用场景对比
在Java编程世界中,Java SE(Java Standard Edition)和Java EE(Java Enterprise Edition)是两个重要的平台版本,它们各自有着独特的定位和应用场景。理解它们之间的差异,对于开发者选择合适的技术栈进行项目开发至关重要。
395 1
|
3月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
Java 大视界 -- Java 大数据机器学习模型在自然语言生成中的可控性研究与应用(229)
本文深入探讨Java大数据与机器学习在自然语言生成(NLG)中的可控性研究,分析当前生成模型面临的“失控”挑战,如数据噪声、标注偏差及黑盒模型信任问题,提出Java技术在数据清洗、异构框架融合与生态工具链中的关键作用。通过条件注入、强化学习与模型融合等策略,实现文本生成的精准控制,并结合网易新闻与蚂蚁集团的实战案例,展示Java在提升生成效率与合规性方面的卓越能力,为金融、法律等强监管领域提供技术参考。
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
142 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
160 1
下一篇
oss云网关配置