Java---包装类与泛型
1.包装类1.1 包装类在Java中由于基本数据类型不是继承Object类为了在泛型代码中可以支持基本数据类型Java给每个基本数据类型各自提供了·一个包装类。如下图除了char和int基本数据类型的包装类型有点特别其他的都是首字母大写1.2 装箱与拆箱1. 装箱装箱就是将基本数据类型的数据转化成包装类装箱分为自动装箱和显示拆箱。public static void main(String[] args) { int a10; Integer bInteger.valueOf(a);//显示装箱 Integer ca;//自动装箱 }其实自动拆箱和显示拆箱的底层原理是一样的都是调用了Integer.valueOf()方法。2. 拆箱拆箱就是将包装类的数据类型转换转换成基本数据类型拆箱也分为自动拆箱和显示拆箱。public static void main1(String[] args) { Integer a10; int ba.intValue();//显示拆箱 int ca;//自动拆箱 }2.面试题了解装箱与拆箱我们来看一道面试题public static void main(String[] args) { Integer a100; Integer b100; System.out.println(a b);//打印true Integer c200; Integer d200; System.out.println(c d);//打印false }为什么会打印不同的结果呢我们来看Integer.ValueOf()方法的原码我们发现在进行装包操作的时候会根据装包的数据的大小来返回不同类型的数据。当要装包的数据的范围在 [-127~128] 之间时valueOf 方法就会返回数组中的一个数据整数。如下图当数据不在上面的范围时就会返回一个新的实例化的对象。所以由于100在【128~127】这个范围内所以两者的比较是两个整数之间的比较。由于200超出了以上范围所以c和d的比较实际上是两个对象之间的比较有来比较两个对象返回值当然是false。2. 泛型2.1 泛型的概念一般类和方法只能使用具体的数据类型要么是基本数据类型或者是引用数据类型。当我们要编写设计多种数据类型的程序时一旦我们将数据类型固定那么对于后续的编程的限制会很大。所以在Java中提出了泛型的概念所谓泛型就是将数据类型参数化。2.2 引出泛型我们先来看一道题实现一个类该类中有一个可以存储任何数据类型的数组并且可以通过方法来设置数组中的值和获取数组中对应的内容。代码如下图在类中我们创建了一个Object类型的数组这样就可以存储任何数据类型了。但是后面我们发现我们可以通过方法来直接设置数组中的内容但是我们通过方法来获取数据类型的时候却发现会报错这是因为发生了向下转型我们需要进行强制类型转换才能正确获得数组中的任何数据。这样想想就很奇怪了我明明可以存储任何数据类型但却不能直接1获取数组中的数据。为了解决这个问题我们就可以使用泛型。如以下代码class DataBaseE{ Object[] arraynew Object[10]; public void setArray(int pos,E obj){ array[pos]obj; } public E getArray(int pos){ return (E)array[pos]; } } public class Test { public static void main(String[] args) { DataBaseInteger dataBasenew DataBase(); dataBase.setArray(0,10); Integer adataBase.getArray(0); DataBaseString dataBase1new DataBaseString(); dataBase1.setArray(1,man); String strdataBase1.getArray(1); } } E 就是泛型的用法可以发现当我们使用泛型之后我们就可以直接来获取数据了不用进行强制转换了。简单来说使用泛型就行我们在创建类的时候通过泛型我们可以将数据类型转换为参数来进行类的创建。如上图我们在实例化database对象的时候我们将Integer的数据类型作为参数传过去所以此时对于字母E就代表Integer数据类型实例化database1的时候我们将String数据类型作为参数传过去此时对于database1来说字母E就代表String类型。注意事项E可以理解为一个标识符代表该类为泛型类。2.3 泛型的语法class 类名T{ }类名后的T是一个标识符表示当前类为泛型类。 其中 里面也可以是其他字母常见的有T和E。3.泛型类的使用3.1 语法格式泛型类名类型实参 变量名new 泛型类名类型实参();举例class MyFuncT{ } public class Test { public static void main(String[] args) { MyFuncInteger myFuncnew MyFuncInteger(); MyFuncString myFunc1new MyFunc(); } }在创建泛型类对象时后面的new 里面的包装类可以不写编译器会根据前面的包装类来推导后面的包装类类型。注意事项泛型只能接受类所有的基本数据类型必须使用包装类。4. 裸类型了解裸类型是一种不带参数的泛型类型它是为了兼容以前老版本JDK没有泛型的版本。例如MyArrayList就是一个裸类型。5. 擦除机制泛型是如何进行编译的呢泛型是编译时期的机制代码在运行的时候没有泛型的概念。这就涉及到擦处机制在编译完成后所有的传给泛型类的数据类型最终都会被擦除为Object类。所以编译之后的字节码无泛型只有Object类。6. 泛型的上界在定义泛型类时有时需要对传入的类型变量进行限制这时候可以通过类型边界来限制。6.1 语法class 泛型类名称类型形参 extends 类型边界 { ... }举例这时定义的泛型类时传入的类型参数的上界为Number传如的类型参数必须是Number的子类由于String类不是Number的子类所以会报错。注意事项没有泛型边界的默认边界为Object。6.2 复杂例子题目要求创建一个类里面有一个方法来获取数组中的最大值。我们会很直接的写下以下代码当我们写出上图的代码之后我们发现会报错。这是因为泛型类的E代表很多数据类型我们不能用平常的数学思维去比较。这时候我们可以对传入的类型参数实现comparable接口来解决问题。class AlgE extends ComparableE{ public E FindMax(E[] array){ E maxarray[0]; for(int i1;iarray.length;i){ if(array[i].compareTo(max)0){ maxarray[i]; } } return max; } } public class Test { public static void main(String[] args) { Integer[] array{1,2,3,4,5}; Alg algnew Alg(); int retalg.FindMax(array); } }这时由于我们在定义泛型类的时候使用了Comparable接口所以此时传入的类型参数必须实现Comparable接口否则会报错。7. 泛型方法7.1 语法格式方法修饰限定符 类型参数 返回值类型 方法名(){ }举例public staticE extends ComparableE E FindMax(E[] array)以上题目获取最大值的另一种代码形式class Alg{ public staticE extends ComparableE E FindMax(E[] array){ E maxarray[0]; for(int i1;iarray.length;i){ if(array[i].compareTo(max)0){ maxarray[i]; } } return max; } } public class Test { public static void main(String[] args) { Integer[] array{1,2,3,4,5}; Alg algnew Alg(); Integer retAlg.FindMax(array);//使用类型推导 Integer ret2Alg.IntegerFindMax(array);//不使用类型推导 } }感谢观看。