- 泛型的基本应用
泛型可以解决类型的安全性问题,其主要原理是在类声明时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或者实例化只要指定好需要的类型即可,
【泛型类定义格式】
[访问权限]class 类名称<泛类型标识1,泛型类标识2,.....,泛型类标识3>
{
[访问权限] 泛类型标识 变量名称;
[访问权限] 泛类型标识 方法名称(){};
[访问权限] 返回值类型声明 方法名称(泛型类型标识 变量名称){};
}
下面使用以上定义类声明对象:
【声明泛型】
class Point<T>
{
private T var;
public T getVar(){
return var;
}
public void setVar(T var){
this.var=var;
}
}
上面的代码中Point类在声明时使用了“”的形式,T表示此类型是由外部调用本类时指定的,这里使用任意的字母都可以。之后在类中定义的var属性的类型也是T,这就表示var这个属性的类型也是由外部来决定的,不是固定类型。同理,setter方法中参数类型以及getter方法中的返回值类型也由外部指定。
运行结果:
public class GenericsDemo05
{
public static void main(String args[])
{
Point<Integer> p=new Point<Integer>();
p.setVar(30);
System.out.println(p.getVar()+1);
}
}
运行结果:
31
以上程序将Point类中的var属性设置成Integer类型,所以在声明及实例化对象时使用Point。这样实际上面的getter和setter方法就变成了如下格式:
public Integer getVar(){
return var;
}
public void setVar(Integer var){
this.var=var;
}
以上的代码只是对设置泛型后的一种说明。
按照上面的方法还可以设置Point的var属性为String类型。
如果设置的泛型类型与指定的泛型类型不一致,则在编译时会出错。
Point<Integer> p=new Point<Integer>();
p.setVar("zhangsan");
System.out.println(p.getVar());
编译时会出现如下的错误:
GenericsDemo05.java:25: 错误: 不兼容的类型: String无法转换为Integer
p.setVar("zhangsan");
^
此时泛型指定的类型是Integer类型,所以如果将其设置字符串内容是就会出现以上的错误。
- 使用泛型修改代码
讲解的坐标类要保证X和Y坐标的数据类型一致,所以最好应用泛型,按照泛型的要求将Point类代码修改如下:
class Point<T>
{
private T x;
private T y;
public T getX(){
return this.x;
}
public void setX(T x){
this.x=x;
}
public T getY(){
return this.y;
}
public void setY(T y){
this.y=y;
}
}
外部使用时:
public class GenericsDemo05
{
public static void main(String args[])
{
Point<Integer> p=new Point<Integer>();
p.setX(10);
p.setY(50);
int x=p.getX();
int y=p.getY();
System.out.println("X:"+p.getX());
System.out.println("Y:"+p.getY());
}
}
运行结果:
X:10
Y:50
如果此时Y坐标设置的不是Integer类型,那么在编译时就会因为传递的数据类型不一致而编译错误。
- 泛型应用中的构造方法
构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定,而又需要通过构造设置属性内容属性时,就可以将泛型应用在构造方法上,此时的构造方法的定义与之前没有什么不同。
【泛型类的构造方法定义】
class Point<T>
{
private T var;
public Point(T var){
this.var=var;
}
public T getVar(){
return var;
}
public void setVar(T var){
this.var=var;
}
};
public class GenericsDemo08
{
public static void main(String args[])
{
Point<String> p=new Point<String>("张三");
System.out.println("var:"+p.getVar());
}
}
运行结果:
var:张三
上面的构造方法和前面的程序是一样的,也就是说即便有泛型声明,也只是在类的定义上声明,而与构造方法的定义无关。
- 指定多个泛型类型
如果一个类中有多个属性需要使用不同的泛型声明,则可以在声明类的时候指定多个泛型类型。
【设置多个泛型类型】
class Point<N,A>
{
private N name;
private A age;
public N getName(){
return this.name;
}
public void setName(N name){
this.name=name;
}
public A getAge(){
return this.age;
}
public void setAge(A age){
this.age=age;
}
};
public class GenericsDemo08
{
public static void main(String args[])
{
Point<String,Integer> p=new Point<String,Integer>();
p.setName("张三");
p.setAge(20);
System.out.println("name:"+p.getName()+" age:"+p.getAge());
}
}
运行结果:
name:张三 age:20
上面的程序中设置类两个属性,并且属性的数据类型由外部决定。