泛型·学习笔记

"嗨,阿米戈!"

"嗨,艾莉!"

"今天,Rishi 和我将向大家介绍仿制药。"

"等等,我想我几乎什么都知道了。"

"几乎所有,但不是所有。"

"真的吗?好吧,我准备好倾听了。"

"那我们开始吧。"

"在 Java 中,泛型是具有类型参数的类。"

"至于为什么要发明泛型,看代码中的注释:"

例子

复制代码
ArrayList stringList = new ArrayList();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // Add a number to the list

for(Object o: stringList)
{
 String s = (String) o; // There will be an exception here when we get to the integer
}

如何使用泛型解决问题:

例子

复制代码
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // There will be a compilation error here

for(Object o: stringList)
{
 String s = (String) o;
}

"这段代码根本无法编译,并且在编译期间会注意到由于添加错误的数据类型而导致的错误。"

"是的,我已经知道了。"

"好,好。重复是学习之母。"

"但是 Java 的创建者在创建泛型时有点懒惰。他们没有制作带有参数的完整类型,而是进行了巧妙的优化。实际上,他们没有向泛型添加任何有关类型参数的信息。相反,所有的编译过程中会发生魔法。"

泛型代码

复制代码
List<String> strings = new ArrayList<String>();
strings.add("abc");
strings.add("abc");
strings.add( 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}

真正发生了什么

复制代码
List strings = new ArrayList();

strings.add((String)"abc");
strings.add((String)"abc");
strings.add((String) 1); // Compilation error

for(String s: strings)
{
 System.out.println(s);
}

"那很光滑。"

"是的,但是这种方法有一个副作用。 泛型类内部不存储类型参数的信息。 这种方法后来被称为类型擦除。"

"换句话说,如果你有自己的带有类型参数的类,你就不能在类中使用关于它们的信息。"

泛型代码

复制代码
class Zoo<T>
{
 ArrayList<T> pets = new ArrayList<T>();

 public T createAnimal()
 {
  T animal = new T();
  pets.add(animal)
  return animal;
 }
}

真正发生了什么

复制代码
class Zoo
{
 ArrayList pets = new ArrayList();

 public Object createAnimal()
 {
  Object animal = new ???();
pets.add(animal)
  return animal;
 }
}

"在编译期间,所有参数类型都被替换为 Object。并且在类内部没有关于传递给它的类型的信息。"

"是的,我同意,那不是最好的。"

"没那么可怕,我稍后会告诉你如何解决这个问题。"

但还有更多。Java 允许您为类型参数指定父类型。extends 关键字用于此。例如:

泛型代码

复制代码
class Zoo<T extends Cat>
{
 T cat;

 T getCat()
 {
  return cat;
 }

 void setCat (T cat)
 {
  this.cat = cat;
 }

 String getCatName() { return this.cat.getName(); }
}

真正发生了什么

复制代码
class Zoo
{
 Cat cat;

 Cat getCat()
 {
  return cat;
 }

 void setCat(Cat cat)
 {
  this.cat = cat;
 }

 String getCatName() { return this.cat.getName(); }
}

"注意两个事实:"

"首先,你不能只传递任何类型作为参数------你只能传递 Cat 或继承 Cat 的类。"

"其次,在 Zoo 类内部,类型 T 的变量现在可以调用 Cat 类的方法。 右侧的列解释了原因(因为 Cat 将在任何有 T 的地方被替换)"

"是的。如果我们说 Cat 或 Cat 的子类作为类型参数传递,那么我们可以肯定类型 T 将始终具有 Cat 类的方法。"

"嗯,这很聪明。"

相关推荐
十年编程老舅10 分钟前
Linux DRM:底层逻辑与实践架构
数据库·mysql
七老板的blog13 分钟前
当 Spring StateMachine 遇见大模型:构建工业级 AI 写作流水线
java·人工智能·spring
小小编程路15 分钟前
Python 还有容器类型互转、进制转换、字符编码转换
开发语言·windows·python
The Sheep 202327 分钟前
Vue复习
linux·服务器·数据库
云烟成雨TD32 分钟前
Spring AI 1.x 系列【46】MCP Security 模块
java·人工智能·spring
CRMEB系统商城34 分钟前
CRMEB多商户系统(Java)v2.3公测版发布
java·开发语言·人工智能·小程序·开源·php
云边有个稻草人40 分钟前
深度解析:KingbaseES高可用架构落地原理与生产运维实战
数据库·读写分离·数据库运维·金仓数据库·国产数据库技术·数据备份恢复
sinat_2554878141 分钟前
第七部分。介绍MVC(模型-视图-控制器)模式
java·ide·http·tomcat·intellij-idea
Samooyou1 小时前
RAG项目案例--02在线检索&过滤流水线
人工智能·python·ai·全文检索·检索
动能小子ohhh1 小时前
DocForge平台的设计与开发--文件上传接口的实现
开发语言·人工智能·python·langchain·ocr·fastapi