泛型·学习笔记

"嗨,阿米戈!"

"嗨,艾莉!"

"今天,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 类的方法。"

"嗯,这很聪明。"

相关推荐
Li emily3 小时前
解决了加密货币api多币种订阅时的数据乱序问题
人工智能·python·api·fastapi
Dicky-_-zhang3 小时前
消息队列Kafka/RocketMQ选型与高可用架构:从单体到100万TPS的演进
java·jvm
晨曦中的暮雨3 小时前
4.15腾讯 CSIG云服务产线 一面
java·开发语言
2301_781571423 小时前
Golang格式化输出占位符都有什么_Golang fmt占位符教程【通俗】
jvm·数据库·python
fake_ss1983 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
养肥胖虎3 小时前
RAG学习笔记(3):区分数据库检索与RAG的使用场景
数据库·ai·rag
asdzx673 小时前
使用 Python 为 PDF 添加页码 (详细教程)
python·pdf·页码
茉莉玫瑰花茶4 小时前
工作流的常见模式 [ 1 ]
java·服务器·前端
AI技术控4 小时前
《Transformers are Inherently Succinct》论文解读:从“能表达什么”到“多紧凑地表达”
人工智能·python·深度学习·机器学习·自然语言处理
_ku_ku_4 小时前
数据库系统原理 · 数据库应用开发 · 自学总结
数据库