1.泛型概述
泛型(Generics),泛型是在jdk1.5以后出现的新特性,用于解决安全问题,是一个类型安全机制。
使用泛型好处:
(1).类型安全提高 Java 程序的类型安全,通过知道使用泛型定义的变量的类型限制,将运行时期的类转换异常体现在编译时期;
(2).消除强制类型转换 消除源代码中的许多强制类型转换,这使得代码更加可读,并且减少了出错机会;
(3).潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
2.泛型修饰
(1).自定义泛型类
(2).自定义泛型方法
(3).自定义泛型接口
3.泛型实现细节
(1).左右两侧泛型声明应相同
Person<String> p1 = new Person<String>();
Person<Integer> p2 = new Person<Integer>();
(2).泛型左右范围
可以限定集合中的输入类型,挡住源程序中非法字符输入,编译完成后,去掉所加的泛型信息。p1.getClass() == p2.getClass();//true
(3).向指定了泛型的集合添加其它类型数据
List<Integer> list = new ArrayList<Integer>();
list.add(12);
list.add(11);
list.getClass().getMethod("add", Object.class).invoke(list, "today");//通过反射添加
for(Object obj: list){
System.out.println(obj);
}
4.泛型限定
(1).通配符<?>,也可以理解为占位符
?通配符只能调用与参数化无关的方法,不能调用与参数化有关的方法
(2).上限:<? extends E>,可以接收E类型或者是E类型的子类 List<Integer> x;
List<? extends Number> y;
y = x; //true Integer 继承了Number
x = y; //false 应注意这种区别
(3).下限:<? super E>,可以接受E类型或者E的父类型,通常用的不多.
5.得到集合泛型类型
//得到集合的泛型类型
public class Test {
public static void main(String[] args) throws Exception{
Method m = Test.class.getMethod("app", ArrayList.class);//对象下面的app函数
Type[] types = m.getGenericParameterTypes(); //可能会接收多个泛型
ParameterizedType pType = (ParameterizedType)types[0];
System.out.println(pType.getRawType()); //class java.util.ArrayList
System.out.println(pType.getActualTypeArguments()[0]); //数组 class cn.Person
}
public static void app(ArrayList<Integer> a) {
}
}
6.自定义泛型方法细节
7.泛型的代码实现
(1).自定义泛型类和静态方法
import java.util.*;
class Person<T> //泛型类
{
private T var;
public void set(T var)
{
this.var = var;
}
public T get()
{
return var;
}
// public static void method(); //静态方法不可以访问类上定义的泛型,static方法属于类
public static <T> void method(); //可以将泛型定义在static方法上。
}
class GenericDemo
{
public static void main(String[] args)
{
Person<String> p1 = new Person<String>();
p1.set("name"); //Person<String>定义与类Person一一对应(Person<T>)!
Person<Integer> p2 = new Person<Integer>();
p2.set(12);
System.out.println(p1.get());
System.out.println(p2.get());
}
}
(2).自定义泛型方法
//泛型方法Strawberry2013-4-29
import java.util.*;
class Demo
{
public <T> void show(T t) //泛型位置处在 返回值的前面,修饰符的后面!
{
System.out.println(t);
}
}
class GenericDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show("hhe");
d.show(3);
}
}
(3).自定义泛型接口
import java.util.*;
interface Info<T> // 在接口上定义泛型
{
public T getVar(); // 定义抽象方法,抽象方法的返回值就是泛型类型
}
class InfoImpl implements Info<String> // 定义泛型接口的子类
{
private String var ; // 定义属性
public InfoImpl(String var) // 通过构造方法设置属性内容
{
this.setVar(var) ;
}
public void setVar(String var)
{
this.var = var ;
}
public String getVar()
{
return this.var ;
}
}
public class GenericsDemo25
{
public static void main(String arsg[])
{
Info i = null; // 声明接口对象
i = new InfoImpl("汤姆") ; // 通过子类实例化对象
System.out.println("内容:" + i.getVar()) ;
}
}
(4).通配符<?>
//?通配符,也可以理解为占位符
import java.util.*;
class Demo<T>
{
private T t;
public void set(T t)
{
this.t = t;
}
public T get()
{
return t;
}
}
class GenericDemo
{
public static void main(String[] args)
{
Demo<String> d1 = new Demo<String>();
d1.set("haha");
Demo<Integer> d2 = new Demo<Integer>();
d2.set(123);
method(d1);
method(d2);
}
public static void method(Demo<?> d) //Demo<?>任意类型的
{
System.out.println(d.get());
}
}
(5).<? extends E>
import java.util.*;
class Person
{
private int age;
Person(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
class Student extends Person
{
Student(int age)
{
super(age);
}
}
class Worker extends Person
{
Worker(int age)
{
super(age);
}
}
class GenericDemo
{
public static void main(String[] args)
{
TreeSet<Student> ts1 = new TreeSet<Student>(new Comp());
ts1.add(new Student(20)); //TreeSet<E>(Comparator<? super E> comparator)
ts1.add(new Student(10));
ts1.add(new Student(30));
TreeSet<Worker> ts2 = new TreeSet<Worker>(new Comp());
ts2.add(new Worker(12));
ts2.add(new Worker(32));
ts2.add(new Worker(22));
method(ts1);
method(ts2);
}
public static void method(TreeSet<? extends Person> d)
{
Iterator<? extends Person> it = d.iterator();
while(it.hasNext())
{
System.out.println(it.next().getAge());
}
}
}
class Comp implements Comparator<Person> //TreeSet(Comparator<? super E> comparator)
{ //E的父类 <? super E>
public int compare(Person p1, Person p2)//Person p = new Student(12);
{
return p1.getAge() - p2.getAge(); //只能使用父类的方法
}
}