1.什么是泛型?
所谓的泛型就是在类定义时,不为类中属性和方法指定数据类型,而是在类对象创建时为其指定相应的数据类型。我们常见的List<T>,使用的就是泛型;
2.为什么需要使用泛型?
使用泛型可以解决数据类型的安全问题;
举个例子:
现有需求:创建一个Point对象,拥有属性X和Y,X和Y的数据类型可以是int、double、String类型;
要实现这个需求,我们可以将X和Y属性都定义为Object属性,但是当输入的X和Y的数据类型不同时,就违背了设计要求,也就是所说的数据类型的安全问题;使用泛型即可解决此问题,同时满足改需求;
public class Point<T> {
//x坐标----
T x;
//y坐标
T y;
//输出坐标的值
public void show(){
System.out.println("x坐标:"+x+";y坐标:"+y);
}
//坐标为整数int--自动装箱->Integer--->Object(向上转型)
Point<Integer> p1=new Point<Integer>(10,20);
p1.show();
//坐标为小数
Point<Double> p2=new Point<Double>(25.5,36.6);
p2.show();
//坐标为字符串
Point<String> p3=new Point<String>("东经180度","北纬25度");
p3.show();
3.如何定义泛型
泛型的使用范围很广、可以定义在类、方法、接口上,这样的类、方法和接口被称为泛型类、泛型方法和泛型接口
泛型可以解决数据类型安全问题,在于类创建时通过一个标识,表示类中的属性的数据类型或者方法的返回值类型或参数类型,这样只需要在声明类或者实例化的时候指定好改标识的数据类型即可
语法格式:
public class 类名<泛型标志,泛型标志....>{
//类成员
}
例如:
public class Apple<T> {
private T weight;
public Apple(T weight) {
this.weight = weight;
}
public T getWeight() {
return weight;
}
public void setWeight(T weight) {
this.weight = weight;
}
}
public static void main(String[] args) {
Apple<String> a1 = new Apple<String>("500克");
System.out.println("a1的weight属性为:"+a1.getWeight());
Apple<Integer> a2 = new Apple<Integer>(500);
System.out.println("a2的weight属性为:"+a2.getWeight());
Apple<Double> a3 = new Apple<Double>(500.0);
System.out.println("a3的weight属性为:"+a3.getWeight());
}
4.通配符
在开发过程中引用传递是一种常见的现象,而在泛型相关的引用传递中,要求传递时的泛型类型必须匹配才可以实现正常的传递,否则将报错。如果通过重写不同泛型类型来解决这个问题,显然不合理,那么我们就可以通过将泛型类型定义为?通配符类解决。
5.受限泛型
在引用传递中,在泛型操作中也可以设置一个泛型对象的==范围上限==和==范围下限==。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型或者此类型的父类型。
语法:
[设置上限]
声明对象: 类名称<? extends 类> 对象名称;
定义类: [访问权限] 类名称<泛型标识 extends 类>{}
[设置下限]
声明对象: 类名称<? super 类> 对象名称;
定义类: [访问权限] 类名称<泛型标识 super 类>{}
例如:
public class Test02 {
public static void main(String[] args) {
People p1 = new People();
p1.setAge(22);
fun(p1);
}
/*super 指定泛型下限,传递过来的泛型数据类型必须为Number类的父类或Number类本身*/
public static void fun(People<? super Number> people){
people.show();
}
}
/*extends 指定泛型上限,指定类的泛型时,必须为Number类的子类或Number本身*/
class People<T extends Number >{
private T age;
public void show(){
System.out.println("这个人的年龄为:"+age);
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
}
6.泛型接口
在jdk1.5以后泛型就可以定义在接口上了
语法:
public interface 接口名<泛型标志,泛型标志....>{
//静态常量
//抽象方法。
}
例如:
public interface Action<T> {
void eat(T thing);
}
public class People implements Action<String>{
@Override
public void eat(String thing) {
System.out.println("吃"+thing);
}
}
public class Test01 {
public static void main(String[] args) {
People p1 = new People();
p1.eat("苹果");
}
}
7.泛型方法
在方法中定义泛型与类是否为泛型类无关;
泛型方法的语法:
[访问权限] ==<泛型标识>== 泛型标识 方法名称(泛型标识 参数名称)
public class Test {
public static <T> T eat(T id){
return id;
}
public static void main(String[] args) {
int id = 222;
System.out.println(eat(id));
}
}