首页 / JAVA / java 泛型 精析
java 泛型 精析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java 泛型 精析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4825字,纯文字阅读大概需要7分钟。
内容图文
![java 泛型 精析](/upload/InfoBanner/zyjiaocheng/848/5cf17252311d42e39d7e487966f073f4.jpg)
Created by Marydon on
1.概述
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数;
这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法;
引入泛型的好处在于:编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”;
“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的;
对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
还是不理解什么是泛型?
定义方法时,我们一般声明具体的入参类型及参数名称,这时,我们称之为:方法的形参,在调用该方法时,传入的参数叫做实参;
而当我们在定义方法时,方法的入参不明确入参的具体类型,和参数名一样,使用变量声明(如:T),这时,我们称其为:类型形参,
在调用该方法时,指定实际传入的参数的数据类型(如:String)叫做类型实参。
再举个例子
// 都是典型的泛型例子 List<String> list = new ArrayList<String>(); Map<String, Object> map = new HashMap<String, Object>();
2.泛型的特性:类型擦除
类型擦除就是说Java泛型只能用于在编译期间的静态类型检查,然后编译器生成的代码会擦除相应的类型信息,这样到了运行期间实际上JVM根本就知道泛型所代表的具体类型。这样做的目的是因为Java泛型是1.5之后才被引入的,为了保持向下的兼容性,所以只能做类型擦除来兼容以前的非泛型代码。对于这一点,如果阅读Java集合框架的源码,可以发现有些类其实并不支持泛型。
// List测试 List<String> list = new ArrayList<String>(); List<Integer> list2 = new ArrayList<Integer>(); System.out.println(list2.equals(list));// true List<Object> list3 = new ArrayList<Object>(); System.out.println(list3.equals(list2));// true List<Object> list4 = new ArrayList<Object>(); System.out.println(list4.equals(list3));// true List<Map<String, String>> list5 = new ArrayList<Map<String, String>>(); System.out.println(list5.equals(list4));// true List<Map<Object, Object>> list6 = new ArrayList<Map<Object, Object>>(); System.out.println(list6.equals(list5));// true // Map测试 Map<String, String> map = new HashMap<String, String>(); Map<Object, Object> map2 = new HashMap<Object, Object>(); System.out.println(map2.equals(map));// true Map map3 = new HashMap(); System.out.println(map3.equals(map2));// true // 赋值后比对 map.put("", ""); map2.put("1", null); System.out.println(map2.equals(map));// false
3.泛型方法
当返回类型为类型变量、入参包含类型变量或这2个条件同时满足时,这时,我们就可以称该方法为:泛型方法;
泛型方法可以定义在普通类中,也可以定义在泛型类中;
类型变量名称需采用使用大写,需用尖括号括起来;
类型变量位于修饰符的后面,返回类型的前面;
泛型方法的入参,可以有多个类型变量。
当泛型方法在普通类中时,
// 普通类 public class People { // 泛型方法:入参和返回值都是类型变量 static <T> T say(T word) { T sentence = null; sentence = (T) ("传入的值是:" + word); return sentence; } }
当泛型方法在泛型类中时,
类型变量既可以声明,也可以不声明;
不声明<T>时,不能是静态方法(不能被static修饰)。
// 泛型类 public class People <T> { // 泛型方法 方式一: static <T> T say(T word) { T sentence = null; sentence = (T) ("传入的值是:" + word); return sentence; } // 泛型方法 方式二: T say2(T word) { T sentence = null; sentence = (T) ("传入的值是:" + word); return sentence; } }
泛型方法的调用
第一种调用方式:
在方法名前的尖括号中放入具体的类型;
声明<T>的情况
// 声明类型参数 String result = People.<String>say("Marydon"); System.out.println(result);
未声明<T>的情况
// 声明类型参数 String result3 = (String) People.class.newInstance().<String>say2("Lucy"); System.out.println(result3);
第二种调用方式:
泛型方法调用中是可以省略<String>
类型参数的,编译器会使用类型推断来推断出所调用的方法。
声明<T>的情况
// 省略<String>类型参数 String result2 = People.say("Marydon"); System.out.println(result2);
未声明<T>的情况
// 省略<String>类型参数 String result4 = (String) People.class.newInstance().say2("Lucy"); System.out.println(result4);
4.泛型类
一个泛型类就是具有一个或多个类型变量的类。
类型变量名称使用大写形式,且比较短,如:T;
需用尖括号括起来,并放在类名的后面;
public class People <T> {}
在Java库中,使用变量E表示集合的元素类型,K
和V
分别表示表的关键字与值的类型,T
表示“任意类型”;
泛型类可以有多个类型变量;
public class People <T, O, P> {}
泛型类定义中的类型变量可以指定为:局部变量、方法的入参、方法的返回值;
/** * 泛型类 */ public class People <T> { // 泛型局部变量 private T kind; // 泛型方法-返回值是泛型 public T getKind() { return kind; } // 泛型方法-入参是泛型 public void setKind(T kind) { this.kind = kind; } }
泛型类可以看成是普通类的工厂。
泛型类的调用
通过类名调用静态方法时,不能指定类型参数;
// 正确方式 String result2 = People.say("Marydon"); // 错误方式 String result2 = People<String>.say("Marydon");
实例化对象时,既可以指定类型参数,也可以不指定。(最好指定)
// 指定类型参数 People<String> p = new People<String>(); // 不指定类型参数 People p2 = new People();
5.泛型接口
6.类型通配符
相关推荐:
?
内容总结
以上是互联网集市为您收集整理的java 泛型 精析全部内容,希望文章能够帮你解决java 泛型 精析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。