一、通配类 到 泛型:
对于以前我们对于自定义通配类型的写法可能如下:
定义学生类和工人类:
class Student
{
Student()
{
System.out.println("我是学生!");
}
}
class Worker
{
Worker()
{
System.out.println("我是工人!");
}
}
定义通用类:
class Tool
{
private Object obj;
public void setObj(Object obj)
{
this.obj = obj;
}
public Object getObj()
{
return obj;
}
}
主函数类:
class GenericDemo
{
public static void main(String[] args)
{
Tool t=new Tool();
t.setObj(new Worker());
//类型强转
Worker w = (Worker)t.getObj();
System.out.println(w);
}
}
但是如果把主函数中的new Worker()
改为new Student()
:
t.setObj(new Student());//t.setObj(new Worker());
//类型强转
Worker w = (Worker)t.getObj();
编译仍旧不会出错,但是运行便会报错。存在安全问题。所以我们使用泛型来保证安全问题:
解决办法:
定义类的时候使用泛型。
//泛型定义在-----类----上
class Utils<T>
{
private T t;
public void setObj(T t)
{
this.t = t;
}
public T getObj()
{
return t;
}
}
主函数:
class GenericDemo
{
public static void main(String[] args)
{
Utils<Worker> u=new Utils<Worker>();
u.setObj(new Student());//报错。必须使用u.setObj(new Worker());
Worker w=(Worker)t.getObj();
System.out.println(w);
}
}
二、泛型除了可以定义在类上外:
1、还可以定义在 方法 上
2、还可以在泛型类里面去写非本类的泛型方法,并且保证不冲突:
3、还可以定义在接口上
一、定义在方法上:
//泛型定义在-----方法----上
class Demo
{
public <T> void show(T t)//这个T:Type只在该方法有效,和下面那个T没关系
{
System.out.println("show:"+t);
}
public <T> void print(T t)
{
System.out.println("print:"+t);
}
}
主函数:
class GenerDemo
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show(new Integer(6));
d.show("asc");
d.print('X');
}
}
二、在泛型类里面去写非本类的泛型方法
class Demo<T>
{
public void show(T t)//这个T:Type只在该方法有效,和下面那个T没关系
{
System.out.println("show:"+t);
}
public <ET> void print(ET et)//ElementType:ET
{
System.out.println("print:"+et);
}
//关于静态方法特例
public static void method(T t)
{
System.out.println("method:"+t);
}
}
解释:
- 先看
show()
方法:public 修饰符的后面并没有泛型,所以是跟随着类上的泛型在走的。 - 再看
print()
方法:public修饰符的后面有泛型,所以其可以接收任何类型并打印。 - 最后看
method()
方法。这样写编译时会报:无法从静态上下文引用非静态类的意思。因为静态方法在定义时,参数类型必须明确。那什么时候才能明确呢?只有在建立对象时才能明确。所以静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据不确定,可以将泛型定义在方法上。如下:
//关于静态方法特例
public <T> static void method(T t)
{
System.out.println("method:"+t);
}
三、定义在接口上(简言之就是在类的基础上向上延伸)
interface DemoPapa<T>
{
void show(T t);
}
//实现接口
class Demo<T> implements DemoPapa<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
public <ET> void print(ET et)
{
System.out.println("print:"+et);
}
}
主函数:
class GenericDemo
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.show("asc");
d.print('X');//Character
d.print(new Integer(5));
}
}