泛型
1. 泛型的引出
现在要求定义一个表示坐标的操作类(Point),在这个类里面要求保存有以下几种坐标·保存数字: x= 10, y= 20;
·保存小数: x= 10.2, y= 20.3;
·保存字符串: x= 东经20度, y= 北纬15度。
现在这个Point类设计的关键就在于x与y这两个变量的类型设计上。必须有一种类型可以保存这
三类数据,那么首先想到的是Object类型:
·int: int自动装箱为Integer, Integer向上转型为Object;
·double: double自动装箱为Double, Double向上转型为Object;
·String: 直接向上转型为Object。
由于Object会有向下转型的安全隐患,所以我们用泛型来实现:
package cn.mldn.demo;class Point<T>{ //T仅仅是一种标记,表示一种类型,在使用Point类才时设置类型
private T x;
private T y;
public void setX(T x) {
this.x = x;
}
public void setY(T y) {
this.y = y;
}
public T getX() {
return x;
}
public T getY() {
return y;
}
}
public class TestDemo {
public static void main(String[] args) {
Point<String> p = new Point<String>();
p.setX("10");
p.setY("20");
System.out.println("x坐标:"+ p.getX() +" y坐标:"+ p.getY());
}
}
使用了泛型之后,所有类中属性的类型都是动态设置的,而所有使用泛型标记的方法参数类型也
都发生改变,这样就避免了向下转型的问题,从而解决了类转换的安全隐患。
但是需要特别说明的是,如果要使用泛型,那么能够采用的类型只能是类,即:不能是基本类型,只能是引用类型。
2. 通配符
package cn.mldn.demo;class Message<T>{
private T msg;
public void setMsg(T msg) {
this.msg = msg;
}
public T getMsg() {
return msg;
}
}
public class TestDemo {
public static void main(String[] args) {
Message<String> m = new Message<String>();
m.setMsg("Hello World!");
fun(m);
}
public static void fun(Message<?> temp) {//不能够设置,但能够取出
System.out.println(temp.getMsg());
}
}
在“?”通配符基础上还会有两个子的通配符:
·?extends 类:设置泛型上限,可以在声明上和方法参数上使用;
- ?extends Number:意味着可以设置Number或者是Number的子类(Integer,Double)
·?super类:设置泛型下限,方法参数上使用
- ?super String:意味着只能够设置String或者是它的父类(Object)
3. 泛型接口
在之前,泛型都是将泛型定义在类里面,那么泛型也可以在接口上声明,称为泛型接口。
package cn.mldn.demo;interface IMessage<T>{
public void print(T msg);
}
class MessageImpl<T> implements IMessage<T>{
@Override
public void print(T msg) {
// TODO Auto-generated method stub
System.out.println(msg);
}
}
public class TestDemo {
public static void main(String[] args) {
IMessage<Integer> msg = new MessageImpl<Integer>();
msg.print(100);
}
}
4. 泛型方法
泛型方法不一定非要定义在支持泛型的类里面。
范例:泛型方法定义package cn.mldn.demo;
public class TestDemo {
public static void main(String[] args) {
String str = fun("Hello");
System.out.println(str.length());
}
//T的类型由传入的参数类型决定
public static <T> T fun(T t){
return t;
}
}
总结:
1.泛型解决的是向下转型所带来的安全隐患,其核心的组成就是在声明类或接口的时候不设置参
数或属性的类型;
2. “?”可以接收任何的泛型类型,只能够取出,不能够修改。