泛型机制
泛型机制是什么
1.泛型概述
泛型机制:是在 JDK 1.5之后引入的一种机制
泛型机制:就是把数据类型明确工作,推迟到创建对象或调用方法时,才去明确的一种机制。
泛型由来:通过Object转型问题引入,早期的Object类型可以接收任意的对象类型,但是在实际的
使用中,会有类型转换的问题,也就存在这隐患,所以Java提供了泛型来解决这个安全问题。
2.泛型的格式:
<数据类型> 这里的数据类型只能是引用数据类型
3.泛型的好处:
(1): 把运行时期的问题提前到了编译期间
(2): 避免了强制类型转换
(3):优化了程序设计,解决了黄色警告线
泛型,只在编译期,有效在运行期,就擦除了。
4.泛型是什么代码举例说明
当使用集合时,如果未使用泛型机制,其代码如下,该集合中可以添加任意类型的对象,但是当加入泛型机制之后,该集合只能根据加入的数据类型进行添加相应的对象,否则会报错,具体如下所示:
public class MyTest {
public static void main(String[] args) {
ArrayList list = new ArrayList();//未加入泛型机制
list.add("abc");
list.add(100);
list.add(3.21);
System.out.println(list);//[abc, 100, 3.21]
System.out.println("==========================");
ArrayList<String> list2 = new ArrayList<String>();//加入泛型机制 指定数据类型为String类型
list2.add("abc");
list2.add("efg")
//list2.add(100); //在这里添加100 给集合中加不进去,因为他不是String类型
list2.add("100");//如果100是字符串类型就可以进行添加
System.out.println(list2);//[abc, efg, 100]
}
}
泛型机制应用
1.自定义类 类型数据的泛型举例
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<>();//创建对象的时候定义类型为Student类型
list.add(new Student("张三",23));
list.add(new Student("张三", 23));
list.add(new Student("张家辉", 23));
list.add(new Student("张震岳", 23));
list.add(new Student("张子豪", 23));
Iterator iterator1 = list.iterator();
while (iterator1.hasNext()) {
Student student1 = (Student) iterator1.next();//迭代器未使用泛型 如果想要得到Student类型的结果 就必须进行向下转型
System.out.println(student1);
}
Iterator<Student> iterator = list.iterator();//迭代器也使用泛型机制
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student);
}
}
}
2.泛型类
(1)泛型类概述:
把泛型定义在类上
(2)定义格式:
public class 类名<泛型类型1,…>
(3)注意事项:
泛型类型必须是引用类型
代码举例说明:
public class MyClass<T> {
private T t;
private Integer num;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
//T可以代表任意引用类型,如下:
public class MyTest {
public static void main(String[] args) {
MyClass<Integer> integerMyClass = new MyClass<>();
integerMyClass.setT(100);
Integer t = integerMyClass.getT();
System.out.println("======================");
MyClass<String> integerMyClass2 = new MyClass<>();
integerMyClass2.setT("abc");
String t1 = integerMyClass2.getT();
}
}
定义泛型类时,可以同时定义多个
public class MyObjct<R,U,M> {//多个类型进行定义
private R r;
private U u;
private M m;
public R getR() {
return r;
}
public void setR(R r) {
this.r = r;
}
public U getU() {
return u;
}
public void setU(U u) {
this.u = u;
}
public M getM() {
return m;
}
public void setM(M m) {
this.m = m;
}
}
public class MyTest2 {
public static void main(String[] args) {
MyObjct<String, Integer,Character> aa = new MyObjct<>();
aa.setU(100);
aa.setR("abc");
aa.setM('a');
String r = aa.getR();
Integer u = aa.getU();
Character m=aa.getM();
System.out.println(r);//abc
System.out.println(u);//100
System.out.println(m);//a
}
}
3.泛型方法
(1)泛型方法概述:
把泛型定义在方法上
(2)定义格式:
public <泛型类型> 返回类型 方法名(泛型类型 变量名)
public class MyDemo {
//如果没有用泛型,定义一个方法,需要指明形参的类型,如下,每定义一个类型,方法都需要重写一次
public void show(Integer num){
System.out.println(num);
}
public void show(String num) {
System.out.println(num);
}
public void show( Double num) {
System.out.println(num);
}
public void show(Object num) {
System.out.println(num);
}
//泛型方法 T可以代表任意引用类型
public<T> void show(T num) {
System.out.println(num);
}
}
4.泛型接口
(1)泛型接口概述:
把泛型定义在接口上
(2)定义格式:
public interface 接口名<泛型类型>
//泛型接口
public interface MyInterface<A> {
public abstract void test(A a);
}
//子类在实现接口时可以给定类型
public class MyA implements MyInterface<Integer>{
@Override
public void test(Integer integer) {
System.out.println("abc");
}
}
//子类在实现时可以不给定类型 但是当具体new MyB对象时需要指定类型
public class MyB<A> implements MyInterface<A>{
@Override
public void test(A a) {
}
}
public class MyTest {
public static void main(String[] args) {
//采用匿名 内部类的这种方式,在创建接口的子类对象时,可以明确接口上的泛型具体是什么类型。
new MyInterface<String>(){
@Override
public void test(String s) {
}
};
//new MyB对象时需要指定类型
MyB<Double> doubleMyB = new MyB<>();
}
}
5.泛型高级通配符
(1)泛型通配符<?>:
任意类型,如果没有明确,那么就是Object以及任意的Java类了
(2)? extends E:
向下限定,E及其子类
(3)? super E:
向上限定,E及其父类
public class MyTest {
public static void main(String[] args) {
//? 泛型通配符
ArrayList<?> objects = new ArrayList<Dog>();
ArrayList<?> objects2 = new ArrayList<Cat>();
ArrayList<?> objects3 = new ArrayList<Animal>();
System.out.println("====================================");
//向上限定 super 子类 父类或者本身
ArrayList<? super Cat> list = new ArrayList<Animal>();
ArrayList<? super Animal> list2 = new ArrayList<Animal>();
ArrayList<? super Animal> list3 = new ArrayList<Object>();
//向下限定 extends 父类 父类或者本身
ArrayList<? extends Animal> list4 = new ArrayList<Animal>();
ArrayList<? extends Animal> list5 = new ArrayList<Cat>();
ArrayList<? extends Animal> list6 = new ArrayList<Dog>();
System.out.println("============================================");
ArrayList<Integer> a= new ArrayList<>();
a.add(200);
ArrayList<Integer> b = new ArrayList<>();
b.add(2000);
a.addAll(b);
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}