黑马程序员——泛型

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

(一).  泛型

1.1 介绍

  泛型是JDK5.0新增加的一个特性,泛型的本质是参数化类型,即所操作的数据类型都被指定为一个参数。这种类型参数可以用在类、接口、和方法的创建中,分别称为泛型类、泛型接口、泛型方法。Java语言引入泛型的好处是安全简单。

1.2 认识泛型

  在JDK5.0之前,没有泛型的情况下,通过对类型Object的引用来实现参数的"任意化",但"任意化"带来的缺点是需要显示的强制类型转换,此种转换要求开发者对实际参数类型预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不会提示错误,但在运行的时候会出现异常,这是一个安全隐患。

1.3 泛型的优势

  使用泛型的优势在于编译期间检查类型,捕捉类型不匹配错误,并且所有的转换都是自动和隐式多的,提高代码复用率。

(二).  泛型的使用 

2.1  泛型定义

  实例化泛型类的语法结构如下:

  1 classname<type-param-list> obj = new classname<type-param-list> (cons-arg-list);  

  泛型定义通常使用一个唯一的大写字母表示一个类型参数。

2.2  代码演示

 1 //创建泛型类
 2 public class Generic <T> {
 3     private T ob;//定义泛型成员变量
 4     public Generic(T ob){
 5         this.ob = ob;
 6     }
 7     public T getOb(){
 8         return ob;
 9     }
10     public void setOb(T ob){
11         this.ob = ob;
12     }
13     public void showType(){
14         System.out.println("实际类型是:" + ob.getClass().getName());
15     }
16 }

  接下来创建类:

 1 //创建测试类,用于解释泛型的使用方法
 2 public class GenericDemo {
 3     public static void main(String[] args) {
 4         //定义泛型类Genneric的一个Integer版本
 5         Generic<Integer> intOb = new Generic<Integer>(88);
 6         intOb.showType();
 7         int i = intOb.getOb();
 8         System.out.println("value=" + i);
 9         System.out.println("---------------------------------");
10         //定义泛型类Genneric的一个String版本
11         Generic<String> strOb = new Generic<String>("Hello");
12         strOb.showType();
13         String s = strOb.getOb();
14         System.out.println("value=" + s);
15     }
16 }

  运行结果:

1 实际类型是:java.lang.Integer
2 value=88
3 ---------------------------------
4 实际类型是:java.lang.String
5 value=Hello

2.3  理解泛型需注意3点

  • 泛型的类型参数是类类型(包括自定义类),不能是基本数据类。
  • 同一种泛型可以对应多个版本(因为类型参数是不确定的),不同版本的泛型类实例是不兼容的。
  • 泛型的类型参数可以有多个。

(三).  有界类型

3.1  介绍

  在有些时候需要对类型参数的取值进行一定程度的限制,以使数据具有可操作性。为了处理这种情况,Java提供了有界类型。在指定类型参数时可以使用extends关键字限制此类型参数代表的类必须继承自指定父类或父类本身。比如创建一个类:public class BoundGeneric<T extends Number>{},BoundGeneric类的定义中,使用extends关键字将T的类型限制为Number类及其子类。

3.2  注意

  在使用extends(如:T extends someClass)声明的泛型类进行实例化时,运行传递的类型参数是:如果someClass是类,可以传递someClass本身及其子类,如果someClass是接口,则可以传递实现接口的类。

3.3  通配符

  通配符由”?“来表示,代表一个未知类型。

  例如:public static void func(Generic <?> T){}或者结合有界类型使用

     public static void func(Generic <? extends Number> T)

(四).  泛型的局限

4.1 泛型的局限性

  其实Java并没有真正的实现泛型,是编译器在编译的时候在字节码上了做手脚(成为擦除),这种实现理念造成java泛型本身有很多漏洞,局限性很大。其中大多数限制性是由类型擦除引起的。

  • 泛型不能被实例化。但可以通过调用Class.newInstance和Array.newInstance方法,利用反射构造泛型对象和数组。
  • 不能实例化泛型数组,即不能创建一个类型特定的泛型引用数组。如:Gen<String> []arrays = new Gen<String> [100];该语句是非法语句,因为会损害类型安全,但是如果使用通配符,就可以创建泛型类型的引用数组,如:Gen<?> []arrays = new Gen<?> [10];
  • 不能用类型参数替换基本类型。因为擦除类型后原先的类型参数被Object或者限定类型替换,而基本类型是不能被对象所存储的,但是可以使用基本类型的包装类来解决此问题。
  • 异常。不能抛出也不能捕获泛型类的异常对象,使用泛型类来扩展Throwable也是非法的。
1 public class GenericException <T> extends Exception{
2     //泛型类无法继承Throwable,非法
3 }

  不能在catch子句中使用类型参数,如下面的方法将不能编译:

1 public static <T extends Throwable> void doWork(Class<T>  t){
2     try {
3     } catch (T e) {//不能捕获类型参数异常
4     }
5 }

  但是,在异常声明中可以使用类型参数。下面这个是合法的:

1 public static <T extends Throwable> void doWork(T t) throws T {
2     try {
3     } catch (Throwable realCause) {//不能捕获类型参数异常
4         throw t;
5     }
6 }
  • 静态成员。不能在静态变量或者静态方法中引用类型参数。如下述语句是非法的:
1 public class Gen<T>{
2     //静态变量不能引用类型参数
3     static T ob;
4     //静态方法不能引用类型参数
5     static T getOb(){
6         return ob;
7     }
8 }

  尽管不能在静态变量或静态方法中引用类型参数,但可以声明静态泛型方法。

(五).  技巧

  当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能将泛型定义在方法上,注意放置位置:public static <Y> void method(Y obj)

  ? extends E :接收E类型或者E的子类对象((对于本身来说是)上限)

  ? super E  :接收E类型或者E的父类型(下限)

  在集合存元素时,一般使用上限,因为这样取出都是按照上限类型来运算,不会出现安全隐患。

  什么时候使用下限呢?

  通常对集合中的元素进行取出操作时,可以用下限。

时间: 2024-08-05 22:46:04

黑马程序员——泛型的相关文章

黑马程序员——泛型认识一

黑马程序员--泛型认识一

黑马程序员 - 泛型和基本类型包装类

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 泛型好处:1.将运行时期的ClassCastException,转移到了编译时期 方便程序员解决问题,让运行时期问题减少. 2.避免了强制转换.泛型格式:通过<>来定义要操作的引用数据类型.通常在集合框架中很常用.泛型类:当类中需要操作的引用数据类型不确定的时候,早期用Object来实现扩展.现在运用泛型类. 当方法中需要操作的引用数据类型不确定的时候,可以运用泛型方法.特殊之处:静态方法,

黑马程序员-泛型

出现原因:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制 好处: 1.将运行时出现的ClassCastException,转移到了编译时期,就是为了方便我们解决问题,让程序运行时出现的问题减少, 2.重要的是:避免的强制类型转换的麻烦 泛型的格式   (通常在集合框架里面用得比较多一点) 用一个<>当中包含一个我们指定的数据类.如ArrayList<String> <>就是用来接收数据类型,就类比函数传参数, 注意:只能传递引用数据类型 java用到

黑马程序员之——Map、泛型、集合框架工具类:Collections,Arrays

第一讲,第二讲:黑马程序员_毕向东_Java基础视频教程第15天-06-集合框架(泛型概述),(泛型使用) 一,泛型了解: 泛型的由来:泛型是JDK1.5版本以后出现的新特性.用于解决安全问题,是一个类型安全机制. 好处:将运行时期出现的问题ClassCastException,转移到了编译时期.方便于程序员解决问题.让运行时期问题减少.安全. 好处:避免了强制转换的麻烦. 二,泛型的格式:通过<>来定义要操作的引用数据类型.    如:ArrayList<String>  //定

黑马程序员-基础加强-泛型

Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换. 这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单. 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者

黑马程序员——Java集合工具类和泛型

Collections工具类和泛型 Collections和Collection Collections和Collection是不同的,Collections是工具类,用来操作集合的,而Collection是集合接口.Collections中有一系列的静态方法用来操作集合,但是不能更改集合内容.比如不能set()不能remove()元素,可以替换全部元素或者添加同一个元素. static List<String> list =Arrays .asList("one Two three

黑马程序员——集合基础知识(泛型)

集合:泛型基础知识 泛型.(泛型就是类型参数化,默认的时object,虽然不用强制类型转换,这个就要你自己去写特性方法,比如compareto是string的特有方法吧,你可以写但是父类肯定调用不了) itnex t对象都是obj要使用对象的特性功能必须强.编译的时候没问题,因为都不知道你会传什么对象,你橙子也可以当作apple来传,设计的时候并不知道! 泛型作用.1.用于解决安全问题.运行时期出现的问题classcastexception转移到编译时期.2.迭代器里面的itnext()不用强转

黑马程序员——java高新---注解、泛型等

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.注解 什么是注解? 答:对于过时的语句,java会提示过时了,通过@SuppressWarnings("Deprecation")可以在DOS命令行中取消提示,但Eclipse无法取消.这就是注解,相当于标记.编译器.开发工具.javac通过反射获得注解里的内容,进而明确应该做什么.不应该做什么.注解可以加在包.类.属性.方法.参数及局部变量之上.一个注解就是一个类. java.

黑马程序员——Java基础---IO(下)

黑马程序员——Java基础---IO(下) ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------ 一.概述 Java除了基本的字节流.字符流之外,还提供了File类.properties类.打印流.序列流等和输入输出相关的类,它们能够帮助我们更好的处理信息.下面将对它们进行简单的介绍. 一.正