我的总结:java泛型

来源:互联网 发布:单片机时间片轮询 编辑:程序博客网 时间:2024/05/18 13:10


本文索引:

 

一   泛型简介

接口的泛型和实现它的类的关系

接口和所带泛型的关系

泛型方法的参数问题

五 独立于类的泛型方法的报错和解决

六 泛型中的重要类型,如:? super Person(或? extends Person)

七总结

一 泛型简介

java的泛型机制是jdk1.5后出现的一种安全机制。它是通过把运行时期可能存在的强制转换中出现的ClassClastException(类型转换异常)转到了编译时期,让程序员在编译时期发现并修改,避免出现不安全问题。所以它主要的功能就是,限制类型。另外有关泛型的补偿机制朋友们也可以去了解一下,这里不作介绍。

二 接口的泛型和实现它的类的关系

一个类实现了一个带有泛型的接口,便有了一些新功能。而如果那个接口里有一部分功能对实现它的类有针对性(或者说这个接口就是为了该类定义的)那么它们之间就有关系。

比如我们可以怎么定义:

//这个接口可以实现比较功能,它所比较的对象和实现它的类相同

interface Comparable<E>{

public boolean CompareTo(E e){}

}

//实现该接口

class Person implements Comparable<Person>{

public boolean CompareTo(Person p){

//代码

}

}

另外一个例子:

集合TreeSet<E>它有一个方法:boolean add(E e)  ,该方法可以添加对象(并按二叉树的性质给所添加对象进行排序)

我们没有学泛型之前这么使用它:

TreeSet ts = new TreeSet(); 

实际上面的代码等于:

TreeSet<Object> ts = new TreeSet<Object>(); 或TreeSet<?> ts = new TreeSet<?>(); 

所以此时没有写泛型就默认是Ojbect类型,而且add可以添加任意对象。

但是如果指定了泛型,那就只可以添加所指定的泛型的对象,比如:

TreeSet<Person> ts = new TreeSet<Person>();

那么ts就只可以添加Person对象因为方法add方法变成add(Person p)。

所以ts和Person建立了关系。

接口和所带泛型的关系

就像第二点所说的:泛型接口和所实现它的类的关系外。另外一种关系是:泛型接口和实现它的类没有关系,但是和接口本身所带的泛型有关系,此时让这个类实现它只是为了new出类具备接口方法的对象。简单说:接口和类没有关系和接口所带泛型有关系。

比如:

//比较器

import java.util.Comparator;
public class ComparatorByName implements Comparator<Person>{

//按Person的属性姓名优先,年龄次之的排序
public int compare(Person p1 , Person p2){
int temp = p1.getName().compareTo(p2.getName());
return temp == 0? p1.getAge() - p2.getAge():temp;
}

}

比较器实现了Comparator接口,目的不是想比较两个比较器对象(这里说接口的泛型和
实现它的类没有关系是因为实现接口不是象上面的第一个Person例子一样比较两个实现类本身的对象)。而是实现了Person对象比较的方法,把这种方法封装在一个类里。作用于Person对象。我把他叫做泛型接口和实现它的类没有关系可是和接口定义的泛型(Person对象)有关系。

怎么作用于Person呢?如下:

TreeSet<Person> ts = new TreeSet<Person>(new ComparetorByName());

泛型方法的参数问题

泛型方法的参数有多少种类型呢,如下:

 

import java.util.Collection;

//自定义一个泛型类

class  MyCollection<E>{

E e;

//方法参数非本类类型

public void method1(Collection<?> coll){}

publilc void methid2(Collection<E> coll){}//和类的泛型一样不需重复在方法上声明

public void method3(Collection<String> cool){}//String Integer 等不需声明在返回值前,访问修饰符后,会默认帮你声明。

//方法参数中的元素是本来体系

public void methid4(Collection<? extends E> cool){}

public void method5(Collection<? super E> cool){}

//方法参数为本类

public void method6(E e){}//和类的泛型一样不需重复在方法上声明

}

五 独立于类的泛型方法的报错和解决

有些方法的方法参数和定义类时类的泛型不一样,并且方法里的操作和类的泛型没有关系。

那么我们可以认为该方法独立于它所在类,它们定义泛型和用泛型参数在方法上完成。这种方法分静态和非静态(如果有返回值那么把void改成泛型,当然下面代码的T可以改为Q什么的,只是一个标记)。如下几种形式等等:

class MyCollection<E>{

//一下方法不是String Integer(包装类类型)等等 并且和类的泛型不一样所以要在方法上声明,不能直接使用!

public <T> void method1(T t){}

public static <T> void method2(T t){}

//public static void method(E e){} 这个是错误的静态方法不可以和类的泛型一样

//这里的<T>是声明小括号里面的是使用

}

六 泛型中的重要类型,如:? super Person(或? extends Person)

  关于这两句代码,我这里不用代码简单介绍一下,这里的Person是一个类。

? super Person代表Person的父类。

? extends Person 代表Person的子类。

详细的就请等下以后的博文了。

七 总结

从3天前开始学泛型,一开始好乱,然后看懂泛型代表什么,接着又不明白它的设计(它的设计或是设计泛型类什么的是我感觉最难的),现在要好好体会它的设计模式。

这篇算是我学泛型的一个阶段性总结,个人水平所限错误之处难免,大家批评指正。

也把它分享给大家,希望共同进步!



0 0
原创粉丝点击