博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
泛型详解
阅读量:3966 次
发布时间:2019-05-24

本文共 5767 字,大约阅读时间需要 19 分钟。

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法

1.泛型的引入

public class TestArrayList {
public static void main(String[] args) {
List list= new ArrayList(); list.add("它"); list.add(2); list.add('b'); list.add(true); int o=(int)list.get(0); System.out.println(o); }}

以上代码存在的问题:集合元素类型不专一, 获取元素必须使用强制类型转换。得到的类型不应该是一个对象,也不确定外界输入的什么所以返回值类型很难确定。这样我们引入泛型使数据类型保持一致。

SinceJDK1.5,提供编译期检查,解决放入集合元素类型不一致的问题,例如:我定义一个ArrayList集合并且规定了只能放置String,如果你放置其他类型就会编译报错.

也就是说Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息给出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。

<>; 用于定义泛型, 钻石运算符,泛型运算符,泛型<>中的字母用什么都行,常用这四个符号表示泛型 T E K V

2.泛型详解

泛型要加的东西放在集合(类,接口)后面(指这个集合(类,接口)只能放指定类型的数据)

public class TestArrayList {
public static void main(String[] args) {
//创建一个ArrayList对象,支持泛型,规定了ArrayList只能存放String类型的元素(对象) List
list = new ArrayList<>(); list.add("ssh"); list.add("wj"); //使用泛型好处:获取元素不用强制类型转换获取元素也能够提供编译检查,由于泛型规定了只能放置String,那么使用非String类型接受,就会编译错误 String s=list.get(0); System.out.println(s); }}

小结:定义ArrayList使用泛型,好处能够在add()方法和get()方法提供编译期类型检查

public class TestArrayList3 {
public static void main(String[] args) {
//泛型:不支持基本类型 //List
list = new ArrayList<>(); List
list = new ArrayList<>(); list.add(1); list.add(1); //Java提供了自动装箱和自动拆箱,放入ArrayList的元素必须是包装类型,取出元素可以用基本类型接受 int num = list.get(0); System.out.println(num); System.out.println(list); }}

3.泛型的使用

泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法

1.泛型类

自己定义一个泛型类, 也可以定义多个泛型,使用逗号分隔就行

可以将泛型用于属性,也可以用于参数,该可以用于返回值

public class GenericClass
{
//定义一个属性,名称叫做name,它在编译期是一个不确定的类型 private T name; public GenericClass() {
} public GenericClass(T name) {
super(); this.name = name; } //T:表示返回类型是一个泛型 public T getName() {
return name; } // T name 表示参数是一个泛型 public void setName(T name) {
this.name = name; } @Override public String toString() {
return "GenericClass [name=" + name + "]"; }}

测试类

public class Demo {
public static void main(String[] args) {
GenericClass
gc = new GenericClass
(); gc.setName("123");//此时就只能传字符串 }}

重点小结:

1.泛型:是一种未知的数据类型,当我们不知道使用什么数据类型的时候可以使用泛型

2.泛型也可以看出是一个变量用来接收数据类型,泛型可以接收任意的引用数据类型,可以使用Integer, String, Student…

3.创建集合对象的时候就会确定泛型的数据类型

2.泛型方法

泛型定义在方法的修饰符和返回值类型之间

格式:修饰符<泛型> 返回值类型方法名(参数列表(使用泛型)){方法体;}

含有泛型的方法,在调用方法的时候确定泛型的数据类型,传递什么类型的参数,泛型就是什么类型

public class GenericMethod {
public
void method1(E e) {
System.out.println(e); } public static
void method2(K k) {
System.out.println(k); }}
public class Demo {
public static void main(String[] args) {
GenericMethod gm = new GenericMethod(); gm.method1(123); GenericMethod.method2("我传的字符串"); }}
3.泛型接口

第一种使用方式: 定义接口的实现类,实现接口时,指定接口的泛型

之前学过的这种泛型接口 Iterator

public interface Iterator
{
boolean hasNext(); E next();}//Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法泛型默认就是Stringpublic final class Scanner implements Iterator
{
public String next() {
}}

自定义一个

public interface GenericInterface
{
public abstract void name(M m); } public class GenericInterfaceImpl implements GenericInterface
{
@Override public void name(String m) {
System.out.println("m"); }}public class Demo {
public static void main(String[] args) {
GenericInterfaceImpl gi = new GenericInterfaceImpl(); gi.name("aaa"); }}

第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走,就相当于定义了一个含有泛型的类,创建对象的时候确定泛型的类型。

之前学过的这种泛型接口 List

public interface List
{
boolean add(E e); E get(int index);}public class ArrayList
implements List
{
public boolean add(E e) {
}public E get(int index) {
}}

自定义

public interface GenericInterface
{
public abstract void name(M m); }public class GenericInterfaceImpl2
implements GenericInterface
{
@Override public void name(M m) {
System.out.println(m); }}public class Demo {
public static void main(String[] args) {
GenericInterfaceImpl2
gi2 = new GenericInterfaceImpl2<>(); gi2.name(123); }}

两者的区别是:第一个实现类在实现接口时就规定了泛型的类型,第二个实现类还是定义的泛型。

4.泛型通配符

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

通配符只能作为方法的参数使用,不能创建对象使用

ArrayList
list=new ArrayList
();//此时会报错:无法实例化类型ArrayList
public class DemoGeneric {
public static void main(String[] args) {
ArrayList
list1=new ArrayList
(); list1.add(5); list1.add(6); ArrayList
list2=new ArrayList
(); list2.add("湖北"); list2.add("湖南"); } //定义一个方法,能遍历所有类型的ArrayList集合,这时候我们不知道ArrayL ist集合使用什么数据类型,可以泛型的通配符?来接收数据类型 //泛型没有继承的概念,所以?不能换成object public static void printArray(ArrayList
list) {
Iterator
iterator = list.iterator(); while(iterator.hasNext()) {
Object obj = iterator.next(); System.out.println(obj); } }}

5.受限泛型

之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在JAVA的泛型中可以指定一个泛型的上限和下限。

泛型的上限: 格式:类型名称<? extends E>对象名称 意义:只能接收E类型及其子类

泛型的下限: 格式:“ 类型名称<? super E>对象名称 意义:只能接收E类型及其父类型

比如:现已知Object类, String 类, Number类, Integer类,其中Number是Integer的父类

public class DemoGeneric {
public static void main(String[] args) {
Collection
list1 = new ArrayList
(); Collection
list2 = new ArrayList
(); Collection
list3 = new ArrayList
(); Collection
list4 = new ArrayList(); //此时只能传Integer和Number getElement1(list1); getElement1(list3); //此时只能传Number和Object getElement2(list3); getElement2(list4); } //此时的泛型必须是Number或者Number的子类 public static void getElement1(Collection
c) { } //此时的泛型必须是Number类型或者是Number的父类 public static void getElement2(Collection
c) { }}

转载地址:http://pqyki.baihongyu.com/

你可能感兴趣的文章
第二章&nbsp;Android内核和驱动程序(转)
查看>>
第二章&nbsp;Android内核和驱动程序(转)
查看>>
第一章&nbsp;Android系统介绍
查看>>
Android电源管理(zz)
查看>>
Android&nbsp;HAL基础
查看>>
Android电源管理(zz)
查看>>
Android平台开发-Android&nbsp;HAL&nbsp;deve…
查看>>
Android&nbsp;HAL基础
查看>>
2011年06月21日
查看>>
Android平台开发-Android&nbsp;HAL&nbsp;deve…
查看>>
Android&nbsp;HAL实例解析
查看>>
2011年06月21日
查看>>
Android&nbsp;HAL实例解析
查看>>
在驱动模块初始化函数中实现设备节…
查看>>
在驱动模块初始化函数中实现设备节…
查看>>
synchronized(this)的意思是:
查看>>
synchronized(this)的意思是:
查看>>
Android&nbsp;USB&nbsp;驱动分析
查看>>
Android&nbsp;Sensor传感器系统架构初探
查看>>
Android&nbsp;Sensor传感器系统架构初探
查看>>