一、泛型的基本应用
泛型可以解决数据类型的安全性问题,主要原理是在类声明时通过一个标识标识类中某个属性的类型或者是某个方法的返回值及参数类型
这样在类声明或实例化时只要指定好需要的类型即可。
泛型类定义 — 格式 1:
[访问权限]class 类名称<泛型类型标识1,泛型类型标识2,...泛型类型标识3>{
[访问权限] 泛型类型标识 变量名称;
[访问权限] 泛型类型标识 方法名称(){};
[访问权限] 返回值类型声明 方法名称(泛型类型标识 变量名称){};
}
泛型类定义 — 格式 2:
类名称<具体类>对象名称 = new 类名称<具体类>();
- 1
class Point<T>{//此处可以是任意的标识符号,T 是 type 的简称
private T var;//此变量的类型由外部决定
public T getVar(){//返回值的类型由外部指定
return var;
}
public void setVar(T var){//设置的类型由外部指定
this.var = var;
}
}
- 6
- 7
- 8
- 9
- 10
这里声明使用了<T>
的形式,T表示此类型是由外部调用本类指定的,这里使用任意的字母都可以,之所以用 T ,因为 T 是 Type 的缩写,比较好理解。
之后设置的 var,setter 方法和 getter 方法类型是 T,表示它们的类型都是外部设置的。
public class Test{
public static void main(String[] args) {
Point<Integer> p = new Point<Integer>();//里面的 var 类型为 Integer
p.setVar(30);
System.out.println(p.getVar() * 2 );
}
}
- 6
- 7
字符串和小数同理,但是此时如果设置的内容和泛型所指定的类型不一样,则在编译时会出错。
加入泛型之后,如果设置的泛型类型是 java.lang.Integer
,实际上对于 setVar()
方法的定义就相当于 public void setVar(Integer var)
其中能接收的只能是整型的数字,如果是一个整数常量,则会采用自动装箱的机制完成。
二、使用泛型修改代码
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 Test{
public static void main(String[] args) {
Point<Integer> p = new Point<Integer>();//定义 Point 对象,指定 Integer 为泛型类型
p.setX(10);//设置整数,自动装箱
p.setY(20);//设置整数,自动装箱
int x = p.getX();//自动拆箱
int y = p.getY();//自动拆箱
System.out.println("整数表示,x 坐标:" + x);//输出信息
System.out.println("整数表示,y 坐标:" + y);
}
}
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
因为这里将 Integer 设置成泛型类型后,setY() 方法能接收的类型就是 Integer,此时如果将其内容设置成 String,将会出现编译错误。
加入泛型的最大好处就是避免了类转换异常的发生,这样使程序的操作更加安全
三、泛型应用中的构造方法
构造方法可以为类中的属性初始化,如果类中的属性通过泛型指定,而又需要通过构造设置属性内容时,构造方法的定义与之前并无不同,不需要像声明类那样指定泛型:
[访问权限] 构造方法 ([<泛型类型>参数名称]){}
- 1
class Point<T>{//指定泛型类型
private T var;//此处可以是任意的标识符号,T 是 type 的简称
public Point(T var){//
this.var = var;
}
public T getVar(){//返回值的类型由外部指定
return var;
}
public void setVar(T var) {//设置的类型由外部指定
this.var = var;
}
}
public class Test{
public static void main(String[] args) {
Point<String > p = null;//定义泛型类对象
p = new Point<String >("Java");//里面的 var 类型为 String
System.out.println("内容:" + p.getVar());//取得字符串
}
}
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
可以看出,即便有泛型声明,也只是在类的定义上声明,而与构造方法的定义无关
四、指定多个泛型类型
如果一个类中有多个属性需要使用不同的泛型声明,则可以在声明类时指定多个泛型类型
class Notepad<K,V>{//此处指定两个泛型类型
private K key;//此变量的类型由外部决定
private V value;//此变量
public K getKey(){//取得 key
return key;
}
public void setKey(K key) {//设置 key
this.key = key;
}
public V getValue() {//取得 value
return value;
}
public void setValue(V value) {//设置 value
this.value = value;
}
}
public class Test{
public static void main(String[] args) {
Notepad<String,Integer> t = null;//定义两个泛型类型的对象
t = new Notepad<>();//默认为 t = new Notepad<String ,Integer>();
t.setKey("Java");
t.setValue(30);
System.out.println("姓名:" + t.getKey());//取得信息
System.out.println("年龄:" + t.getValue());//取得信息
}
}
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
程序中 key 属性为 String 类型,value 属性为 Integer,这两个属性的类型由外部指定。