Java进阶-泛型

泛型

泛型概述
泛型是啥? <字母>
	1.一个<>里面泛型可以有多个,用逗号隔开即可,例如HashMap<K,V>,这就是有两个泛型
	2.一个泛型中最好是单个字母且是大写字母
	
泛型的作用:
	约束集合中元素的数据类型
	
特点:
	1.只能使用引用数据类型去替换泛型存在的位置
	2.泛型是在编译阶段存在的类型约束
	3.如果有泛型,但是不去对泛型操作,去确定泛型类型的话,则泛型默认是Object类型
	
泛型的类型约束只在编译阶段存在
package com.tan.generic;

import java.lang.reflect.Method;
import java.util.ArrayList;

//    反射可以跳过编译阶段
public class ReflectDemo {
public static void main(String[] args) throws Exception {
    ArrayList<Integer> list = new ArrayList<>();
//    泛型是具体使用的时候才确认数据类型
    list.add(1);
//    泛型是编译阶段的类型约束
//    list.add("Hello");
    System.out.println("list = " + list);

    Class aClass = list.getClass();

    Method add = aClass.getDeclaredMethod("add", Object.class);

    add.invoke(list,"HelloWorld");

    System.out.println("list = " + list);
}
}
泛型类
泛型类概述
作用:此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定

格式 :
    public class 类名<泛型>{

    }
泛型类使用样例
//泛型类的定义
package com.tan.generic;

import java.util.Objects;

public class Student<E> {
    private String name;
    private E age;

    public Student() {
    }

    public Student(String name, E age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public E getAge() {
        return age;
    }

    public void setAge(E age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student<?> student = (Student<?>) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


//泛型类的使用
package com.tan.generic;
/*
作用:此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定

格式 :
    public class 类名<泛型>{

    }
注意:
如果子类要沿用父类/父接口的泛型,子类必须也定义泛型
 */
public class GenericClass {
    public static void main(String[] args) {
//        如果有泛型却不处理泛型,那么泛型默认是Object类型
        Student defaultStd = new Student();
        defaultStd.setName("冰墩墩");
        defaultStd.setAge(6);//多态

        Student<String> stringStd = new Student<>();
        stringStd.setName("雪容融");
        stringStd.setAge("5");

        Student<Integer> integerStd = new Student<>();
        integerStd.setName("谷爱凌");
        integerStd.setAge(18);


    }
}

泛型方法
泛型方法概述
泛型方法中的泛型一般用T表示

泛型方法一般都作为形参的数据类型使用, 但是方法泛型的具体类型等调用方法的时候才确定

格式:
	方法的修饰符 <泛型> 返回值类型 方法名(形参列表){
        方法体;
    }
泛型方法使用样例
package com.tan.generic;

/*
泛型方法中的泛型一般用T表示

泛型方法一般都作为形参的数据类型使用, 但是方法泛型的具体类型等调用方法的时候才确定

格式:
	方法的修饰符 <泛型> 返回值类型 方法名(形参列表){
        方法体;
    }

*/

public class GenericMethod {
    public static void main(String[] args) {
        show("HelloWorld");

        show(new Student());
        
    }
    
    public static <T> void show(T t){
        System.out.println("t = " + t);
    }
}

泛型接口
泛型接口概述
此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定

格式 :
    public interface 接口<泛型>{

    }

注意:
如果子类要沿用父类/父接口的泛型,子类必须也定义泛型
泛型接口使用样例
package com.tan.generic;
/*
此类中就多了一种泛型类型给类使用,泛型类型的具体数据类型要等到具体使用这个类的时候才能确定

格式 :
    public interface 接口<泛型>{

    }

注意:
如果子类要沿用父类/父接口的泛型,子类必须也定义泛型

 */

public class GenericInterface {
    public static void main(String[] args) {

    }
}

interface Grandmother<E>{
    public abstract void add(E e);
}

interface Mother<E> extends Grandmother<E>{

}

class Daughter<E> implements Mother<E>{

    @Override
    public void add(E e) {

    }
}
泛型的通配符和泛型的上下限
泛型的通配符和泛型的上下限概述
1.泛型的通配符:?
    ?可以接收任意的引用数据类型

2.泛型的上下限:
    泛型的上限(<=)? extends 类名A
    泛型的下限(>=)? super 类名A
        类名的上下限都包含A类

泛型的通配符和上下限都是方法的形参上使用的
泛型的通配符及上下限使用样例
背景知识:在Java中,存在着Object > Number > Integer的关系

问题描述:
定义一个方法,使该方法可以接收ArrayList<Object>ArrayList<Number>ArrayList<Integer>这三个类型的对象

有两种方式可以便捷实现以上需求:
1.泛型的通配符:?
    其中?可以接收任意的引用数据类型

2.泛型的上下限:
    泛型的上限(<=)? extends 类名A
    泛型的下限(>=)? super 类名A
        其中类名的上下限都包含A类

泛型的通配符和上下限都是方法的形参上使用的
package com.tan.generic;

public class Cola implements Comparable<Cola> {
    @Override
    public int compareTo(Cola o) {
        return 0;
    }
}

package com.tan.generic;

import java.util.ArrayList;
import java.util.Collections;

public class Generate {
    public static void main(String[] args) {
        ArrayList<Object> list1 = new ArrayList<>();
        ArrayList<Number> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();

        wildcardMethod(list1);
        wildcardMethod(list2);
        wildcardMethod(list3);


        /*
            boundMethod(list3);编译错误
                ===> boundMethod (java.util.ArrayList ) in Generate cannot be applied
                to (java.util.ArrayList )

                Generate类中的boundMethod (java.util.ArrayList )方法
                不能被应用于(java.util.ArrayList )



            boundMethod(list1);
                -->ArrayList list = ArrayList list1

            boundMethod(list2);
                -->ArrayList list = ArrayList list2

            boundMethod(list3);
                -->ArrayList list = ArrayList list3

         */
        boundMethod(list1);
        boundMethod(list2);
//        boundMethod(list3);


        ArrayList<Cola> cola = new ArrayList<>();
        Collections.sort(cola);

    }
    public static void boundMethod(ArrayList<? super Number> list){

    }

    public static <T> void wildcardMethod(ArrayList<T> list){

    }
}

 
  

                            
                        
                    
                    
                    

你可能感兴趣的:(Java,进阶,java,开发语言,后端)