文章目录
- 泛型作用: 限制加入集合中元素的类型,将类型限制为同一种类型
- 一.泛型的基本应用
- 二.泛型的扩展
- 1.泛型类
- 1.1 创建泛型类时,类型不确定,只有在创建对象时才确定
- 2.泛型方法
- 2.泛型接口
- 三.泛型受限
- 1.泛型上限:? extends A :只要泛型为A或A的子类都可传入
- 2.泛型下限:? super A : 只要泛型为A或A的父类都可传入
泛型作用: 限制加入集合中元素的类型,将类型限制为同一种类型
泛型在编译期间生效,不允许加入其他类型
一.泛型的基本应用
public class Animal{
public String name;
public String color;
public Animal(String name,String color)
{
super();
this.name = name;
this.color = color;
}
public String toString()
{
return "Animal [name=" + name + ", color=" + color + "]";
}
}
public class AnimalTest
{
public static void main(String[] args)
{
List<Animal> list = new ArrayList<>();
Animal cat = new Animal("cat","White");
Animal dog = new Animal("dog","black");
Animal rabbit = new Animal("rabbit","white");
list.add(cat);
list.add(dog);
list.add(rabbit);
for(Object o : list) { //增强for循环,遍历list,遍历出的每一个对象都用Object类型的o接收
System.out.println(o); //相当于‘Object o=每个对象’,父类引用指向子类对象(Object为如何子类的父类),实则为多态
}
}
}
Output:
Animal [name=cat, color=White]
Animal [name=dog, color=black]
Animal [name=rabbit, color=white]
但是加了泛型之后的遍历
for(Animal a : list) { //遍历list,遍历出的每一个对象都用Animal类型的a接收
System.out.println(a);
}
二.泛型的扩展
1.泛型类
定义泛型类的语法格式
类访问修饰符 class 泛型类名 <类型参数> {
类体
}
类型参数可以用任何单个大写字母表示,通常使用E来表示集合元素类型,用K与V分别表示键-值对中的键类型与值类型,用T、U、S表示任意类型
1.1 创建泛型类时,类型不确定,只有在创建对象时才确定
具体实例:
public class Animal <A> { //在此创建了<A>的泛型类
.....
}
class Test{
public static void main(String[] args){
Animal<Integer> a1 = new Animal<>(); //此时A的类型为Integer
Animal<String> a2 = new Animal<>(); //此时A的类型为String
.....
}
}
2.泛型方法
图中代码,第二个方法的参数类型为A,A即为public class GenericTest< A > 中的泛型A,由于GenericTest< Integer > gt = new GenericTest<>();中已经确定< A >的类型为Integer,所以
gt调用方法时,b方法确定为Integer。
c方法,由于方法的参数类型为B,B不是public class GenericTest< A > 中的泛型A,所以在方法体内加入< B >,否则会报错。由于B的加入,B为不确定类型,即任意类型都可。
因此,c方法帮我们解决了不同数据类型做参数的重载问题。通俗而言,如果想要传入不同类型的数据,不用写不同参数类型的方法,只需写public< B > void c(B b)即可实现。注意:
如果在方法中加入static,则b方法报错,c方法可以。
原因是,static修饰的方法存在于对象之前,由于泛型A的类型在创建对象时确定,所以a方法报错。然而,c方法不受类型限制,因此static对此方法没有限制。
2.泛型接口
泛型接口的定义格式如下:
interface 接口名<类型参数列表>
{
...
}
在实现接口时,也应当声明与接口相同的类型参数。格式如下:
class 类名<类型参数列表> implements 接口名<类型参数列表>
{
...
}
具体实例如下:
在实现类classA中确定了泛型A为String类型。
注意: 实现类class B中的泛型是BB不是泛型A,BB类型为不确定型,因此会报错。应当改成:class B < BB>implements GenericInterface< BB>{}
三.泛型受限
1.泛型上限:? extends A :只要泛型为A或A的子类都可传入
2.泛型下限:? super A : 只要泛型为A或A的父类都可传入
public class Person{
public String name;
public int age;
public Person(String name, int age)
{
super();
this.name = name;
this.age = age;
}
@Override
public String toString()
{
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Student extends Person{
public int id;
public Student(String name, int age, int id)
{
super(name, age);
this.id = id;
}
@Override
public String toString()
{
return "Student [id=" + id + "]";
}
}
import java.util.ArrayList;
class Test{
public static void main(String[] args) {
ArrayList<Person> a1= new ArrayList<Person>();
a1.add(new Person("nana",18));
a1.add(new Person("haha",19));
show(a1);
ArrayList<Student> a2= new ArrayList<Student>();
a2.add(new Student("yiyi",20,1));
a2.add(new Student("bobo",21,2));
show(a2);
}
public static void show(ArrayList<? extends Person> ab) { //泛型上限
for(Person a : ab) {
System.out.println(a);
}
}
}
Output:
Person [name=nana, age=18]
Person [name=haha, age=19]
Student [id=1]
Student [id=2]