Java:泛型
泛型Generic:
泛型:是JDK1.5版本后出现的新特性,用于解决安全问题的一个安全机制(针对集合的特性)。
例如:ArrayList<String> al = new ArrayList<String>();
Iterator<String> it = al.iterator();
泛型的好处:1、将运行时期出现的ClassCastException问题,转移到编译时期,方便程序员解决问题,让运行时期问题减少,安全。
2、避免强制转换的麻烦。
泛型的格式:通过<>来定义要操作的引用数据类型。
说明:在使用java提供的对象时,什么时候写泛型?
通常在集合框架种中很常见,只要见到<>就要定义泛型。其时<>就是用来接受类型的,当使用集合时,将集合中要存储的类型传递给<>中即可。
//例子1:
import java.util.*; class Generic { public static void main(String[] args) { ArrayList<String> al = new ArrayList<String>(); al.add("sdgh"); al.add("123"); al.add("de"); // al.add(4); //al.add(new Integer(4)); //编译时期就会出现错误,产生ClassCastException问题 Iterator<String> it = al.iterator(); while(it.hasNext()) { // String s = (String) it.next(); String s = it.next(); //因为Iterator已经声明了String类型,所以不必再进行强制转换了 System.out.println(s+":"+s.length()); } } }
泛型方法(非静态方法、静态方法)
(一)泛型类定义的泛型,在整个类中有效.如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
class Demo1<T> //仅在类上定义泛型...
{
public void show(T t)
{
System.out.println("T:"+t);
}
public void print(T t)
{
System.out.println("T:"+t);
}
}
(二)为了让不同的方法操作不同类型,而且类型还不确定,那么可以将泛型固定在方法上
//例子2:
class Demo2 { public<T> void show(T t) //仅在方法上定义泛型... { System.out.println("T:"+t); } public<Q> void print(Q q) //仅在方法上定义泛型... { System.out.println("Q:"+q); } } /* (三)类上定义泛型,也在方法上定义泛型 */ class Demo3<T> //在类上定义泛型... { public void show(T t) { System.out.println("T:"+t); } public<Q> void print(Q q) //在方法上定义泛型... { System.out.println("Q:"+q); } //特殊之处:静态方法不可以访问在类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。 public static<W> void get(W w) //在静态方法上定义泛型... { System.out.println(w); } } class GenericFunction { public static void main(String[] args) { Demo1<String> d1 = new Demo1<String>();//该类中的没有定义泛型的方法中要操作的参数只能是String类型 d1.show("abc"); d1.print("aaa"); System.out.println(); Demo1<Integer> d2 = new Demo1<Integer>();//该类中的没有定义泛型的方法中要操作的参数只能是Integer类型 d2.show(new Integer("123")); d2.show(new Integer(120)); d2.print(4); System.out.println(); Demo2 d3 = new Demo2();//该类中的定义过泛型的方法要操作的参数可以是任意类型 d3.show("abc"); d3.print("aaa"); d3.show(new Integer("123")); d3.show(new Integer(120)); d3.print(4); System.out.println(); Demo3<String> d4 = new Demo3<String>();//该类中的没有定义泛型的方法中要操作的参数只能是String类型, d4.show("abc"); //而该类中的定义过泛型的方法要操作的参数可以是任意类型 d4.print(new Integer(120)); d4.print("aaa"); Demo3.get("xyz"); //调用定义了泛型的静态方法 Demo3.get(new Integer(100)); //调用定义了泛型的静态方法 Demo3.get(20); //调用定义了泛型的静态方法 } }
泛型类,格式是:class 类名<T>{}
什么时候用泛型类?
当类中要操作的引用数据类型不确定时,早期定义Object来完成来扩展;现在用定义泛型类来完成扩展。
class Worker
{…...}
class Student
{…….}
泛型以前的做法
class Tool
{
private Object obj;
public void setObject(Object obj)
{
this.obj = obj;
}
public Object getObject()
{
return obj;
}
}
//例子3:
//泛型类 class Tool2<QQ> { private QQ q; public void setObject(QQ q) { this.q = q; } public QQ getObject() { return q; } } class GenericClass { public static void main(String[] args) { /* Tool t1 = new Tool(); t.setObject(new Worker()); t.setObject(new Student());//由于setObject函数接受的类型为Object,所以编译和运行时期不会出错 Worker w = (Worker)t1.getObject();//返回的Object必须强转为Worker */ Tool2<Worker> t2 = new Tool2<Worker>(); t2.setObject(new Worker()); // t.setObject(new Student());//由于setObject函数接受的类型为Worker,所以编译时期就会出错 Worker w = t2.getObject(); //不用再强转 } }
接口的泛型
//泛型定义在接口上
interface Inter<T> //泛型定义在接口上 { void show(T t); } class Interimlp1 implements Inter<String>//只能接受字符串类型的参数 { public void show(String s) { System.out.println("show:"+s); } }
//泛型定义在类上
class Interimlp2<T> implements Inter<T> { public void show(T t) { System.out.println("show:"+t); } } class GenericInterface { public static void main(String[] args) { Interimlp1 i1 = new Interimlp1(); i1.show("abc");//只能传递字符串类型的参数 System.out.println(); Interimlp2<Integer> i2 = new Interimlp2<Integer>(); i2.show(new Integer(123));//只能传递Integer类型的参数 i2.show(10); } }
泛型的限定:可以用占位符表示<?>
<?>:通配符,也可以说是占位符
泛型的限定:分上限、下限
上限:<? extends E>:可以接受E类型或E的子类型
下限:<? super E>:可以接受E类型或E的父类型
//例子4:
import java.util.*; class GenericLimited { public static void main(String[] args) { ArrayList<String> al1 = new ArrayList<String> (); al1.add("abc1"); al1.add("abc2"); al1.add("abc3"); ArrayList<Integer> al2 = new ArrayList<Integer> (); al2.add(4); al2.add(7); al2.add(5); ShowCollEle(al1); ShowCollEle(al2); } public static void ShowCollEle(ArrayList<?> al) //用通配符表示泛型 即 ArrayList<?> al = new ArrayList<任意类型>() { Iterator<?> it = al.iterator(); //用通配符表示泛型 即 ArrayList<任意类型> al = al.iterator() while(it.hasNext()) { System.out.println(it.next()); } } /* public static <T> void ShowCollEle(ArrayList<T> al) // 即 ArrayList<T> al = new ArrayList<任意类型>() { Iterator<T> it = al.iterator(); // 即 ArrayList<任意类型> al = al.iterator() while(it.hasNext()) { T t = it.next(); System.out.println(t); } } */ }
//例子5:泛型上限
import java.util.*; class Person { private String name; Person(String name) { this.name = name; } public String getname() { return name; } } class Student extends Person { private String name; Student(String name) { super(name); } } class GenericLimited2 { public static void main(String[] args) { ArrayList<Person> al1 = new ArrayList<Person> (); al1.add(new Person("abc1")); al1.add(new Person("abc2")); al1.add(new Person("abc3")); ShowCollEle1(al1); ArrayList<Student> al2 = new ArrayList<Student> (); al2.add(new Student("abc11")); al2.add(new Student("abc22")); al2.add(new Student("abc33")); ShowCollEle1(al2); //ArrayList<Person> al2 = new ArrayList<Student>();//error } //上限 public static void ShowCollEle1(ArrayList<? extends Person> al) { Iterator<? extends Person> it = al.iterator(); while(it.hasNext()) { System.out.println(it.next().getname()); } } }
//例子6:泛型下限
import java.util.*; class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public String getname() { return name; } public int getage() { return age; } } class Student extends Person { private String name; private int age; Student(String name,int age) { super(name,age); } } class GenericLimited3 { public static void main(String[] args) { TreeSet ts = new TreeSet(new Mycomparator()); ts.add(new Person("xyz1",11)); ts.add(new Person("xyz2",10)); ts.add(new Person("xyz3",15)); ts.add(new Person("xyz4",19)); showTreeSet(ts); } //下限 public static void showTreeSet(TreeSet<? super Student> ts) { Iterator<? super Student> it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next().getage()); } } } class mycomparable implements Comparable<Person> //<? super Student> { public int compareTo(Person p) { } } class Mycomparator implements Comparator<Student> { public int compare(Student s1,Student s2) { } }