建设网站费用一般多少,中国历任总经理名单,昆明网站空间,好看的页面图片目录 一. 包装类
1.1 基本数据类型和对应的包装类
1.2 装箱和拆箱 二. 泛型
2.1什么是泛型
2.2泛型的引入 2.3 泛型类语法 2.4 泛型类的使用 2.5 裸类型(Raw Type)(了解) 2.6 泛型是如何编译的
2.7 泛型的上界
2.8 泛型方法 一. 包装类 在 Java 中#xff0c;由于基本…目录 一. 包装类
1.1 基本数据类型和对应的包装类
1.2 装箱和拆箱 二. 泛型
2.1什么是泛型
2.2泛型的引入 2.3 泛型类语法 2.4 泛型类的使用 2.5 裸类型(Raw Type)(了解) 2.6 泛型是如何编译的
2.7 泛型的上界
2.8 泛型方法 一. 包装类 在 Java 中由于基本类型不是继承自 Object 为了在泛型代码中可以支持基本类型 Java 给每个基本类型都对应了一个包装类型。 1.1 基本数据类型和对应的包装类 包装类在之前我们就使用过, 使我们写代码更加的方便
1.2 装箱和拆箱
装箱(装包): 把一个基本数据类型转变为包装类型
拆箱(拆包): 把一个包装类型转变为基本数据类型 int i 10 ; Integer ii i ; // 自动装箱 Integer ii Integer . valueOf ( i ); //显示装箱 ---类名.valueOf 说明该方法时用static修饰的 Integer jj new Integer(10) ; int j jj ; // 自动拆箱 int j jj . intValue (); //显示拆箱 注:拆箱时, 我们可以将数据拆成我们想要的类型 Integer jj new Integer(10); double d jj.doubleValue();//拆成double类型 System.out.println(d); //输出结果 10.0 下面看一道面试题: 思考 : 为什么上述代码只是将100改成200, 输出的结果却不同呢? 上述我们唯一做的动作就是装箱, 那么装箱时, 调用的方法是Integer.valueOf(), 按住Ctrl点进去查看valueOf的源码, 我们发现: 我们传入的参数, 如果在一个low和high之间, 那么就返回一个数组某下标的值, 如果不在这个范围内, 那么就new一个对象, 此时即使传入一样的参数, 返回的值肯定是不同的. 那么我们猜测, 200就不在low和high之间, 而100在low和high之间. 那么我们点进去low和high的源码, 发现low -128 , high 127, 我们的猜测是正确的, 那么cache数组是怎么回事呢? 我们计算一下这个数组: 二. 泛型
2.1什么是泛型 一般的类和方法只能使用具体的类型 : 要么是基本类型要么是自定义的类。如果要编写可以应用于多种类型的代码这种刻板的限制对代码的束缚就会很大。 ----- 来源《 Java 编程思想》对泛型的介绍。 泛型是在 JDK1.5 引入的新的语法通俗讲泛型 就是适用于许多许多类型 。从代码上讲就是对类型实现了参数化。 2.2泛型的引入 实现一个类类中包含一个数组成员使得数组中可以存放任何类型的数据也可以根据成员方法返回数组中某个下标的值. 思路 1. 我们以前学过的数组只能存放指定类型的元素例如 int[] array new int[10]; String[] strs new String[10]; 2. 所有类的父类默认为 Object 类。数组是否可以创建为 Object? 代码示例 问题 以上代码实现后 发现 1. 任何类型数据都可以存放 2. 1 号下标本身就是字符串但是确编译报错。getPos返回值是Object, 用String接收, 必须进行强制类型转换 虽然在这种情况下当前数组任何数据都可以存放但是更多情况下我们还是希望他只能够持有一种数据类型。而不是同时持有这么多类型。所以泛型的主要目的就是指定当前的容器要持有什么类型的对象。让编译 器去做检查。 此时就需要把类型作为参数传递。需要什么类型就传入什么类型。 那么我们对上述代码进行改写: ① MyArrayT ----- 类名后的 T 代表占位符表示当前类是一个泛型类 了解 【规范】类型形参一般使用一个大写字母表示常用的名称有 E 表示 Element K 表示 Key V 表示 Value N 表示 Number T 表示 Type S, U, V 等等 - 第二、第三、第四个类型 ②T[] array (T[])new Object[10] ---- 创建泛型类数组
T[] array (T[])new Object[10], 并不是一个最好的写法, 最好的写法是:
Object[] array new Object[10]; 不能new泛型类型的数组 T [] ts new T [ 5 ]; // 是不对的 ③ MyArrayInteger myArray new MyArray() ----- 创建泛型类对象, 类型后加入 Integer 指定当前类型 后面的中的内容可以省略
④ myArray.setVal(2,bit) ----- 代码编译报错此时因为在③处指定类当前的类型此时编译器会在存放元素的时候帮助我们进行类型检查。
泛型, 是编译时期的机制, 在运行时, 没有泛型的概念
注:中的内容不能是基本数据类型, 只能是引用类型/包装类
想要存放String类型的数据: 2.3 泛型类语法 class 泛型类名称 类型形参列表 { // 这里可以使用类型参数 } class ClassName T1 , T2 , ..., Tn { } class 泛型类名称 类型形参列表 extends 继承类 /* 这里可以使用类型参数 */ { // 这里可以使用类型参数 } class ClassName T1 , T2 , ..., Tn extends ParentClass T1 { // 可以只使用部分类型参数 } 2.4 泛型类的使用 泛型类 类型实参 变量名 ; // 定义一个泛型类引用 new 泛型类 类型实参 ( 构造方法实参 ); // 实例化一个泛型类对象 MyArray Integer list new MyArray Integer (); //当编译器可以根据上下文推导出类型实参时可以省略类型实参的填写 MyArray Integer list new MyArray (); // 可以推导出实例化需要的类型实参为 Integer 注意泛型只能接受类所有的基本数据类型必须使用包装类 2.5 裸类型(Raw Type)(了解)
裸类型是一个泛型类但没有带着类型实参例如 MyArrayList 就是一个裸类型 MyArray list new MyArray(); 小结 1. 泛型是将数据类型参数化进行传递 2. 使用 T 表示当前类是一个泛型类。 3. 泛型目前为止的优点数据类型参数化编译时自动进行类型检查和转换 2.6 泛型是如何编译的 那么泛型到底是怎么编译的这个问题也是曾经的一个面试问题。泛型本质是一个非常难的语法要理解好他还是需要一定的时间打磨。 通过命令 javap -c 查看字节码文件所有的 T 都是 Object 。 在编译的过程当中将所有的 T替换为Object 这种机制我们称为 擦除机制 。 Java 的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。 2.7 泛型的上界 在定义泛型类时有时需要对传入的类型变量做一定的约束可以通过类型边界来约束。
语法: class 泛型类名称 类型形参 extends 类型边界 { ... } 例: public class MyArray E extends Number { ... } 表示: 只接受 Number 或 Number的子类型 作为 E 的类型实参 MyArray Integer l1 ; // 正常因为 Integer 是 Number 的子类型 MyArray String l2 ; // 编译错误因为 String 不是 Number 的子类型 了解
1. 没有指定类型边界 E可以视为 E extends Object
2. 泛型没有下界 例: 写一个泛型类, 求一个数组中的最大值 显然这样是错误的, 因为擦除机制将T替换成Object类, 而引用类型是不能直接比较大小的, 需要使用compareTo方法, 并实现Comparable接口, 我们点进去Object的源码看发现: Object类并没有实现Comparable接口 正确的写法应该是: 意味着, 传入的参数必须是继承了Comparable接口的类, 那么Integer我们点进去查看: Integer是继承了Comparable接口的. 如果我们重新定义一个类当参数: 是不被允许的, 因为没有Person没有实现Comparable接口 正确写法: 2.8 泛型方法
语法: 方法限定符 类型形参列表 返回值类型 方法名称 ( 形参列表 ) { ... } 上述代码可以写成 泛型方法: 当这个泛型方法是静态的时, 我们就不用实例化对象, 直接通过类来调用泛型方法