看这一章花了好些时间,直到现在依然有一些不明朗的地方。如果有个人认识不正确的地方,烦请指出。
1.
引用
有许多原因促成了泛型的出现,而最引人注目的一个原因,就是为了创造容器类。
class Automobile {}
public class Holder1 {
private Automobile a;
public Holder1(Automobile a) {this.a = a;}
public void set(Automobile a) { this.a = a; }
public Automobile get() { return a; }
}
这个类持有一个Automobile类型的对象a,但重用性很差,如果要持有其他非Automobile类型需重写。
public class Holder2 {
private Object a;
public Holder2(Object a) { this.a = a; }
public void set(Object a) { this.a = a; }
public Object get() { return a; }
}
这个类持有Object类型的对象a,但可以往里随意set各种类型的对象。但我们只需要持有一种特定类型,并且想保证类型的正确性,所以请用泛型吧。
public class Holder3<T> {
private T a;
public Holder3(T a) { this.a = a; }
public void set(T a) { this.a = a; }
public T get() { return a; }
public static void main(String[] args) {
Holder3<Pet> h3 = new Holder3<Pet>(new Cat());
h3.set(new Dog());
Pet a = h3.get();
}
}
这个类持有的是T类型的对象a,当创建Holder3对象时,只需告诉编译器要使用Pet类型。并且当h3对象被创建出来,它就只能持有Pet类型或其子类型,如本例中的Cat和Dog,但你不能给它set People类型的对象,即编译器会做类型检查。
2.Java泛型局限之一,基本类型无法作为类型参数。但可以使用包装类型,与基本类型进行转换。
3.关于擦除:
引用
在泛型代码内部,无法获得任何有关泛型参数类型的信息
举个例子就是new ArrayList<String>().getClass()与new ArrayList<Integer>().getClass()所得到的是相同的实例。
引用
Java泛型是使用擦除来实现的,这意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。因此List<String>和List<Integer>在运行时事实上是相同的类型。这两种形式都被擦除成它们的“原生”类型,即List。
4.关于边界:
引用
边界使得你可以再用于泛型的参数类型上设置条件。
因为擦除了类型信息,所以类似List<T>这种无界泛型参数的写法实际运行时只认为参数是一个Object类型。设置泛型边界使用
extends关键字,如:class Colored<T extends HasColor>。
5.关于通配符“?”:
假设有如下的类继承关系:
class Fruit {}
class Apple extends Fruit {}
在泛型的使用中,却不能这样初始化:List<Fruit> list = new ArrayList<Apple>();
这里用个人做的练习28的代码来理解用法,注意里面关键字super和extends的使用:
class GenericSet<T> {
public void setMethod(T param) {
}
}
class GenericGet<T> {
private T param;
public T getMethod() {
return param;
}
}
public class Practise28 {
static <T> void setMethod(GenericSet<? super T> param, T item ) {
param.setMethod(item);
}
static <T> void getMethod(GenericGet<? extends T> param) {
param.getMethod();
}
public static void main(String[] args) {
GenericSet<Fruit> individual1 = new GenericSet<Fruit>();
GenericGet<Fruit> individual2 = new GenericGet<Fruit>();
setMethod(individual1, new Apple());
getMethod(individual2);
}
}
6.关于自限定类型:
使用个人做的练习34的代码来理解(不要吐槽命名。。。):
abstract class MyAbstract<T extends MyAbstract<T>>
{
abstract T method(T i);
T invoke(T i) {
System.out.println(i.getClass().getSimpleName());
return method(i);
}
}
public class Practise34 extends MyAbstract<Practise34> {
public static void main(String[] args) {
System.out.println(new Practise34().invoke(new Practise34()));
}
@Override
Practise34 method(Practise34 i) {
return i;
}
}
分享到:
相关推荐
在讨论Java编程思想学习笔记时,首先需要了解的是Java语言的平台无关性,而这一特性正是通过Java虚拟机(JVM)得以实现的。JVM作为Java程序设计的关键组成部分,对于Java开发人员来说是必须掌握的基础知识。在该学习...
### 第三本书:《Thinking in Java》(《Java编程思想》) #### 知识点概述 - **面向对象思想**:深入讲解面向对象的核心思想,如抽象、封装等。 - **泛型与集合**:掌握泛型的使用技巧,了解集合框架的设计理念。 ...
第15章 泛型 第16章 数组 第17章 容器深入研究 第18章 Java I/O系统 第19章 枚举类型 第20章 注解 第21章 并发 第22章 图形化用户界面 附录A 补充材料 可下载的补充材料 Thinking in C:Java的基础 Java编程思想 ...
3.17 操作符小结 3.18 总结 第4章 控制执行流程 4.1 true和false 4.2 if-else 4.3 迭代 4.3.1 do-while 4.3.2 for 4.3.3 逗号操作符 4.4 Foreach语法 4.5 return 4.6 break和 continue 4.7 臭名昭著的“goto” 4.8 ...
#### 小结 本书《Agile Java: Crafting Code with Test-Driven Development》不仅深入浅出地介绍了Java语言的基础知识,还特别强调了敏捷开发理念与测试驱动开发的实际应用。通过阅读本书,读者不仅可以掌握Java...
3.7.6 循环语句小结78 3.7.7 break语句79 3.7.8 continue语句82 3.8 JavaDebug技术84 3.9 本章练习85 第4章 4.1 一维数组90 4.1.1 为什么要使用数组90 4.1.2 什么是数组91 4.1.3 如何使用数组92 4.1.4 经验之谈-数组...
1.5 小结 11 第2章 基本数据类型——构建Java 大厦的基础 12 2.1 源代码注释 12 2.1.1 单行注释 12 2.1.2 区域注释 12 2.1.3 文档注释 13 2.2 基本数据类型 14 2.2.1 整型 15 2.2.2 浮点型 17 ...
本教程主要涵盖了面向对象基础,旨在帮助学习者理解和掌握这一重要编程思想。 1. **程序设计范型**: - **过程式编程**:这是早期的编程方式,侧重于逻辑步骤的分解和执行,通过函数或子程序来处理问题,数据和...
- C#支持现代编程概念,如泛型、lambda表达式、异步编程等。 - C#具有丰富的类库支持,可以通过.NET框架访问数据库、创建图形用户界面等。 - C#具有自动内存管理和垃圾回收机制,减少了内存泄漏等问题。 - **1.4 ...
Ivor Horton是撰著Java、C和C++编程语言图书的杰出作家之一。大家一致认为,他的著作独具风格,无论是编程新手,还是经验丰富的编程人员,都很容易理解其内容。在个人实践中,Ivor Horton也是一名系统顾问。他从事...