泛型的介绍
泛型是JDK 1.5之后添加的新功能。
为什么要使用泛型?
例:假如此时要设计一个表示坐标的类,此时表示类的形式要有三种:int,float,String,则在设计时,要考虑使用一个类型可以同时接收这样的三种数据类型,则现在只能使用Object,因为Object类可以使用任何类型的数据,都会发生自动向上转型操作,这样三种数据类型将按照以下的三种方式进行转换:
int----> 自动装箱成Integer ——向上转型使用Object接收
float——>自动装箱成 Float——向上转型使用Object接收
String——.>向上转型使用Object接收
但是如果 输入的两个数据的数据类型不同,则不能够进行运行,如下面的例子:
class Point{ private Object x ; // 表示X坐标 private Object y ; // 表示Y坐标 public void setX(Object x){ this.x = x ; } public void setY(Object y){ this.y = y ; } public Object getX(){ return this.x ; } public Object getY(){ return this.y ; } }; public class GenericsDemo{ public static void main(String args[]){ Point p = new Point() ; // 声明一个Point的对象 p.setX(10) ; // 利用自动装箱操作:int --> Integer --> Object p.setY("北纬210度") ; // String --> Object int x = (Integer)p.getX() ; // 取出数据先变为Integer,之后自动拆箱 int y = (Integer)p.getY() ; // 取出数据先变为Integer,之后自动拆箱 System.out.println("整数表示,X坐标为:" + x) ; System.out.println("整数表示,Y坐标为:" + y) ; } };
所以此时我们可以不控制数据的输入类型,只限制数据的输出类型,此时就有了泛型,主要原理是在类声明的时候通过一个标示符表示类中的某个属性或者某个方法的返回值及参数类型。这样在类声明或实例化的时候只要指定好需要的类型即可。
泛型类的定义格式
[访问权限]class 类名称 <泛型类型1,泛型类型2,....>
{
[访问权限] 泛型类型标示 变量名称 ;
[访问权限] 泛型类型标示 方法名称( ){};
[访问权限] 返回值类型声明 方法名称 ( 泛型类型标示 变量名称){ };
}
泛型方法的定义格式
类名称 <具体类> 对象名称 = new 类名称 <具体类>();
使用泛型后,可以确保数据的安全性。
class Point<T>{ private T x ; // 表示X坐标 private T y ; // 表示Y坐标 public void setX(T x){ this.x = x ; } public void setY(T y){ this.y = y ; } public T getX(){ return this.x ; } public T getY(){ return this.y ; } }; public class GenericsPoint{ public static void main(String args[]){ Point<Integer> p = new Point<Integer>() ; p.setX(10) ; // 利用自动装箱操作:int --> Integer <span style="color:#ff0000;">p.setY("北纬210度") ; // 利用自动装箱操作:int --> Integer 此处报错,因为将Integer设置成泛型后,setY()方法能接受的只能是Integer //Y设置 成Integer后因为数据类型不一致 所以会报错。</span> int x = p.getX() ; // 自动拆箱 int y = p.getY() ; // 自动拆箱 System.out.println("整数表示,X坐标为:" + x) ; System.out.println("整数表示,Y坐标为:" + y) ; } };
在泛型的应用中最好声明类的时候指定好其内部的数据类型,如Info<String>,但也可以不指定类型,但是这样用户在使用类的时候会出现不安全的警告信息。
泛型操作范例
表示一个人的信息收集类。
interface Info{ // 只有此接口的子类才是表示人的信息 } class Contact implements Info{ // 表示联系方式 private String address ; // 联系地址 private String telphone ; // 联系方式 private String zipcode ; // 邮政编码 public Contact(String address,String telphone,String zipcode){ this.setAddress(address) ; this.setTelphone(telphone) ; this.setZipcode(zipcode) ; } public void setAddress(String address){ this.address = address ; } public void setTelphone(String telphone){ this.telphone = telphone ; } public void setZipcode(String zipcode){ this.zipcode = zipcode ; } public String getAddress(){ return this.address ; } public String getTelphone(){ return this.telphone ; } public String getZipcode(){ return this.zipcode ; } public String toString(){ return "联系方式:" + "\n" + "\t|- 联系电话:" + this.telphone + "\n" + "\t|- 联系地址:" + this.address + "\n" + "\t|- 邮政编码:" + this.zipcode ; } }; class Introduction implements Info{ private String name ; // 姓名 private String sex ; // 性别 private int age ; // 年龄 public Introduction(String name,String sex,int age){ this.setName(name) ; this.setSex(sex) ; this.setAge(age) ; } public void setName(String name){ this.name = name ; } public void setSex(String sex){ this.sex = sex ; } public void setAge(int age){ this.age = age ; } public String getName(){ return this.name ; } public String getSex(){ return this.sex ; } public int getAge(){ return this.age ; } public String toString(){ return "基本信息:" + "\n" + "\t|- 姓名:" + this.name + "\n" + "\t|- 性别:" + this.sex + "\n" + "\t|- 年龄:" + this.age ; } }; class Person<T extends Info>{ private T info ; public Person(T info){ // 通过构造方法设置信息属性内容 this.setInfo(info); } public void setInfo(T info){ this.info = info ; } public T getInfo(){ return this.info ; } public String toString(){ // 覆写Object类中的toString()方法 return this.info.toString() ; } }; public class GenericsDemo33{ public static void main(String args[]){ Person<Introduction> per = null ; // 声明Person对象 per = new Person<Introduction>(new Introduction("李兴华","男",30)) ; System.out.println(per) ; } };