黑马程序员------毕老师视频笔记第13-17天------泛型

时间:2022-09-04 16:20:44

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

用一个事例引出:

import java.util.*;
class Demo
{
public static void main(String[] args)
{
ArrayList al = new ArrayList();
al.add("ghjadsf");
al.add("adsf");
al.add("sfeef");
al.add(4);//自动装箱,集合只能放对象
Iterator it = al.iterator();
while(it.hasNext())
{
String s = (String)it.next();//为了用String类的函数所以强转
System.out.println(s+":"+s.length());
}
}
}

黑马程序员------毕老师视频笔记第13-17天------泛型

编译运行出现异常

Integer对象不能强转成String类型

怎么解决这样的安全隐患呢?

泛型Generic:JDK1.5版本以后出现的新特性,用于解决安全隐患,是一个类型安全机制

 

jdk升级的目的有三个:高效,简化书写,安全

 

数组在定义的时候就明确了元素类型,存其他类型的数据时,编译就会报错,安全。

怎么让集合像数组一样在定义的时候就能明确类型呢?

ArrayList<String> al = newArrayList<String>();

Iterator<String> it = it.Iterator();

这样,编译的时候存了Integer数据就会报错

 

泛型好处:

1.将运行时期出现的问题ClassCastException,转移到了编译时期,方便与程序员解决问题。让运行时期问题减少,安全

2.避免了强制转换的麻烦

 

格式:通过尖括号来定义要操作的引用数据类型

 

在使用java提供的对象时,什么时候写泛型呢?

通常在集合框架中很常见,只要见到尖括号,就要定义泛型。

例如API中Collection<E>,ArrayList<E>等

 

其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 

使用实例:

import java.util.*;
class GenericDemo
{
public static void main(String [] args)
{
TreeSet<String> ts = new TreeSet<String>(new LenComparator());
ts.add("f");
ts.add("sdfg");
ts.add("qwreg");
ts.add("re");
ts.add("reg");
ts.add("reshsd");
Iterator<String> it = ts.iterator();
while(it.hasNext())
{
String s = it.next();
System.out.println(s);
}
}
}
class LenComparator implements Comparator<String>
{
//(Object o1,Object o2),不用泛型函数内要强转
public int compare(String o1,String o2)
{
int num = new Integer(o2.length()).compareTo(new Integer(o1.length()));
if(num == 0)
return o2.compareTo(o1);
return num;
}
}
黑马程序员------毕老师视频笔记第13-17天------泛型

java中预定义了很多泛型类(即使用泛型的类),能不能在自己定义的类中使用泛型呢,即自定义一个泛型类

class Utils<QQ>

{

         privateQQ q;

         publicvoid setObject(QQ q)

         {

                   this.q= q;

}

public QQgetObject()

{

         return q;

}

}

什么时候定义泛型类?

当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。

泛型类定义泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。

 

为了让不同的方法可以操作不同的类型,而且类型还不确定,可以将泛型定义在方法上。

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

public <Q> void print(Q q){}

 

也可以在泛型类中定义泛型方法

class Demo<T>

{

         publicvoid show(T t){}

public <Q>void print(Q q){}

}

 

注意:

1.静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以讲泛型定义在方法上。

2.泛型定义在方法上,要放在返回值类型的前面,固定格式。

 

另外,泛型还可以定义在接口上。

interface Inter<T>

{void show(T t);}

class Interimpl implements Inter<String>

{public void show(String t){}}

class Interimpl2<T> implements Inter<T>

{public void show (T t){}}

 

泛型限定

? 通配符,也可以理解为占位符

? extends E 可以接收E,也可以接收E的子类型,上限

? super E 可以接收E,也可以接收E的父类型,下限

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------