黑马程序员——学习笔记——泛型

来源:互联网 发布:javascript java 编辑:程序博客网 时间:2024/06/06 18:46

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


2014年11月28日

天气  阴转小雨

心情  还行

说实话,了解了下去黑马的流程,好麻烦,不过这样确实好,至少是对我们负责。好啦,不扯了,我就当日记写了,之前学的就不写了,从今天开始吧。哈哈


首先,我理解的泛型就是给我们new出来的类定义他的类型,增强代码的安全性,让我们在编译期就能发现问题,而不至于到运行期才发现问题。

在1.5之后,使用泛型来接收类中要操作的引用数据类型。

1.起因:在我们装入集合的类型都被当做Object对待的时候,会失去自己的实际类型,从集合中取出时也往往需要转型,这样效率很低,还容易产生错误。例如:

public static void main(String[] args) {// TODO 自动生成的方法存根TreeSet<Person> ts = new TreeSet<Person>(new CompatatorByName());ts.add(new Person("lisi", 23));ts.add(new Person("lisiwesd", 28));ts.add(new Person("lisid", 30));ts.add(new Person("lisisa", 21));ts.add(new Person("lisi", 28));Iterator<Person> it = ts.iterator();while(it.hasNext()){Person p = (Person)it.next();System.out.println(p.getName() + " " + p.getAge());}}

在这里面就使用了泛型,首先我们把TreeSet定义成Person类型,Person类使我们自定义的一个类,里面有age 和name这两个属性,里面有他的get,set方法,以及他的构造方法

public class Person{private String name;private int age;public Person() {super();// TODO 自动生成的构造函数存根}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
那么当我们在往ts这个容器里面添加元素的时候,我们就只能添加Person类型的元素,这样是在我们知道我们要添加一些Person类,所以我们加入一个泛型。


2.解决方法:

在定义集合的时候同时定义集合中对象的类型。

1.可以在定义Collection的时候指定。

2.也可以在循环的时候用Iterator指定。

Iterator<Person> it = ts.iterator();
while(it.hasNext()){<span style="white-space:pre"></span>Person p = (Person)it.next();System.out.println(p.getName() + " " + p.getAge());
}

在1.5之前,我们定义一个自定义类是:

public class Tool {private Object object;public Object getObject() {return object;}public void setObject(Object object) {this.object = object;}
}

那么  当我们引用泛型的时候,我们会指定引用类的数据类型:

public class Tool<Q>{private Q q;public Q getObject() {return q;}public void setObject(Q object) {this.q = object;}}

这样,我们在新建新的类时,就可以按照自己的需求来定义:
Tool<Student> tool = new Tool<Student>();
tool.setObject(new Student());Student stu = tool.getObject();

而当我们引用自定义类中的方法的时候 也可以定义泛型,将泛型定义在方法上:

public <W> void show(W str){System.out.println("show:" + str);}public void print(Q str){System.out.println("print: " + str);}

这样,我们可以根据自己想要实现的类型类实现。

但有一个要注意的地方:当方法静态时,不能访问类上定义的泛型,如果静态方法使用泛型,只能讲泛型定义在方法上。 

public static <F> void method(F obj){System.out.println("method:" + obj);}

当然,我们 在定义接口的时候也可以使用泛型,:

interface Inter<T>{public void show(T t);}

这样我们在实现这个接口的时候,也可以根据具体需求来定义不同的类型:

class InterImpl implements Inter<String>{public void show(String str){System.out.println("show:" + str);}}class InterImpl2 <Q> implements Inter<Q>{public void show(Q q){System.out.println("show:" + q);}


泛型的上限下限

上限是为了在存元素的时候能够限定一个最大范围,一般都是通配符 ?extends E ,取E类和E类的子类

private static void printCollection(Collection<? extends Person> al) {//泛型的上限,取Person以及Person的子类Iterator<? extends Person> it = al.iterator();while(it.hasNext()){<span style="white-space:pre"></span>System.out.println(it.next());
<span style="white-space:pre"></span>}
}
下限是为了在取元素的时候能够限定一个最小范围,一般为通配符 ? super E ,取E类和E类的父类
private static void printCollection(Collection<? super Student> al){//泛型的下限,取Student以及Student的父类
Iterator<? super Student> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());



3.好处:

增强程序的可读性和稳定性。

加强编译时期的安全性。

注意:当声明泛型的实例时,传递过来的类型参数必须是类,不能为基本类型。

           运行时,会将泛型去掉,生成的class文件是不带泛型的,这个称为泛型的擦除。



好啦,这是今天学的内容,总结了下就搞过来,明天继续补充,哈哈哈


0 0
原创粉丝点击