【读书笔记】TiJava——泛型
来源:互联网 发布:直销软件开发 编辑:程序博客网 时间:2024/04/30 09:54
import java.util.ArrayList;import java.util.LinkedList;import java.util.List;public class Obj <T> {private T foo;public T getFoo() {return foo;}public void setFoo(T foo) {this.foo = foo;} public void f(Object arg) { <span style="color:#ff6666;">T var = new T(); // Error:Cannot instantiate the type T</span> } }
上面的错误原因是:使用泛型类时,必须在创建对象时指定类型参数。
//------------------------------------------------------------------------------------------------------------------------------------------------------------
类型参数推断
•使用泛型类时,必须在创建对象时指定类型参数。
•使用泛型方法时,不需要指定类型参数。
•方法的泛型返回值(被认为是一个Object类型)作为参数传给另一个方法时,不会执行类型推断,不能编译,除非使用显示类型说明。
擦除
•ArrayList<String>.class== ArrayList<Integer>.class==ArrayList.class
•在泛型代码内部,无法获得任何有关类型参数的信息。
•泛型类型参数擦除到它的第一个边界类型。因此,在泛型类内部,只能调用边界类型定义的方法。
•使用擦除的原因是为保证迁移兼容性,即在类库实现泛型化时,客户端代码无需修改。
编译器对泛型的支持
•泛型类与非泛型类的字节码完全相同。
•在边界处,对传递进来的值进行编译期类型检查,并插入对传出去的值的转型代码(本来需要程序员写代码转型的地方)
擦除的补偿:类型实例
•在泛型类内部创建类型实例的方法
–使用类型标签Class<T>.newIntance(),但依赖于默认构造器。
–使用工厂类,为每个类型定义工厂类,由工厂方法创建类型实例。
–使用模板方法,该模板方法返回类型实例。
擦除的补偿:类型数组
•创建类型数组的方法
–使用ArrayList
–T[]array = (T[]) new Object[]
–使用Object数组,在取的时候转型
–推荐:使用类型标记
•T[] array = (T[]) Array.newInstance(type, size);
其他
•类的static方法无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。
•多个边界时,类写在接口前面
•继承带边界的类时,本类边界必须包含父类边界
通配符?extends
•用于泛型的向上转型,如:
–List<Fruit>list 只能指向 List<Fruit>
–List<?extends Fruit> 可以等于List<Apple>
无界通配符<?>
•表明用泛型编码
•任何基本类型都不能作为类型参数
下面的代码,说明了泛型的使用方法以及场景
package test.generics;import java.lang.reflect.Array;public class GenericFoo<T extends Fruit> { private T[] ta; private Class<T> clz; private T x; public GenericFoo(T x) { this.x = x; //ERROR: Cannot instantiate the type T //this.x = new T(x); //this.x = new T(); } public GenericFoo(Class<T> clz) { //Cannot create a generic array of T //this.ta = new T[3]; //WARNING: Type safety: Unchecked cast from Object[] to T[] this.ta = (T[]) new Object[3]; //best way to create generic array is use Class info //WARNING: Type safety: Unchecked cast from Object to T[] this.ta = (T[]) Array.newInstance(clz, 3); } public T getX() { return x; } public void setX(T x) { this.x = x; }}
package test.generics;import java.util.ArrayList;import java.util.List;
class Fruit {}class Apple extends Fruit {}class Jonathan extends Apple {}class Orange extends Fruit {}
public class TestGenerics { @SuppressWarnings("unused") public static void main(String[] args) { //OK: GenericFoo<Fruit> cli = new GenericFoo<Fruit>(new Fruit()); //ERROR: Type mismatch: cannot convert from GenericFoo<Apple> to GenericFoo<Fruit> //GenericFoo<Fruit> cli2 = new GenericFoo<Apple>(new Apple()); //OK: GenericFoo<? extends Fruit> cli3 = new GenericFoo<Apple>(new Apple()); //ERROR: The method setX(capture#3-of ? extends Fruit) in the type GenericFoo<capture#3-of ? extends Fruit> is not applicable for the arguments (Apple) //cli3.setX(new Apple()); //OK: GenericFoo<?> cli4 = new GenericFoo<Apple>(new Apple()); //ERROR: The method setX(capture#3-of ?) in the type GenericFoo<capture#3-of ?> is not applicable for the arguments (Apple) //cli4.setX(new Apple()); //OK: GenericFoo<? super Apple> cli5 = new GenericFoo<Fruit>(new Fruit()); //ERROR: Type mismatch: cannot convert from GenericFoo<Jonathan> to GenericFoo<? super Apple> //GenericFoo<? super Apple> cli6 = new GenericFoo<Jonathan>(new Fruit()); //ERROR: Bound mismatch: The type TestGenerics is not a valid substitute for the bounded parameter <T extends Fruit> of the type GenericFoo<T> //GenericFoo<TestGenerics> cli = new GenericFoo<TestGenerics>(new Fruit()); //OK: Number[] n = new Integer[3]; n[0] = 1; //OK: //Runtime Exception: Exception in thread "main" java.lang.ArrayStoreException: java.lang.Double //n[1] = 1.1; //OK: List<Number> ln = new ArrayList<Number>(); ln.add(1); //OK: ln.add(1.1); //OK: List<Integer> li = new ArrayList<Integer>(); //ERROR: Type mismatch: cannot convert from List<Integer> to List<Number> //ln = li; //ERROR: Type mismatch: cannot convert from ArrayList<Integer> to List<Number> //List<Number> ln2 = new ArrayList<Integer>(); //ERROR: Cannot create a generic array of ArrayList<String> //List<String>[] lsa = new ArrayList<String>[3]; }}
0 0
- 【读书笔记】TiJava——泛型
- 【读书笔记】TiJava——泛型
- 【读书笔记】TiJava——注解
- 【读书笔记】TiJava——并发
- 【读书笔记】TiJava——内部类
- 【读书笔记】TiJava——持有对象
- 【读书笔记】TiJava——IO系统
- 【读书笔记】TiJava——枚举类型
- 【读书笔记】TiJava——内部类使用范例:温室控制器
- 《Effective java》读书笔记4——泛型
- 泛型——CLR via C# 读书笔记
- 读书笔记——数组
- 结网——读书笔记
- 读书笔记——继承
- 【读书笔记】 —— 金融
- 读书笔记——简介
- 读书笔记—名言积累
- 读书笔记—风险投资基金
- linux学习之--SecureCRT 工具上传下载数据
- STM32F407串口的基本使用
- Android Matrix详解
- 写在200小时
- 原理图检查以及一些错误及原因
- 【读书笔记】TiJava——泛型
- Linux Out-of-Memory分析
- UVa 11078 - Open Credit System
- .NETC#下AE二次开发过程中出现的属性表不能更新问题解决办法
- 用Apache Spark进行大数据处理
- 位运算将01字符串转化为相应二进制数
- Qt的自文档化工具qdoc
- ExpandableListView替换右边箭头的实现
- llwer