JAVA的泛型

一、JAVA的泛型(泛型就是语法糖)

1、泛型类

①只能用在非静态成员变量和非静态成员方法上

②只能代替引用变量

class Student<T>{
    T name;
    public T getName() {
        return name;
    }
}

2、泛型接口

①只能用在抽象方法上,不能用在常量上

interface Human<T>{
    T compareTo(T t);
}

3、泛型方法(静态方法和非静态方法两者皆可以用)

class Method{
    public static <T> void show(T t) {
        
    }
}
class Method2{
    public static <T extends Cloneable> void show(T t) {
        
    }
}

4、泛型继承(四种情况 )

//泛型父类(抽象方法和接口和父类都一样)
abstract class Father<T1,T2>{
    T1 age;
    abstract void test(T2 arg); 
}
//①不指定类shi于:Father<Object,Object>
class Son1 extends Father{
    @Override
    void test(Object arg) {
        // TODO Auto-generated method stub        
    }        
}
class Son11<A,B> extends Father{
    @Override
    void test(Object arg) {
        // TODO Auto-generated method stub        
    }    
}

//②指定具体类型
class Son2 extends Father<Integer,String>{
    @Override
    void test(String arg) {
        // TODO Auto-generated method stub        
    }    
}
class Son22<A,B> extends Father<Integer,String>{
    @Override
    void test(String arg) {
        // TODO Auto-generated method stub        
    }    
}

//③部分保留,泛型子类
class Son3<T1> extends Father<T1,String>{
    @Override
    void test(String arg) {
        // TODO Auto-generated method stub        
    }    
}
class Son33<T1,A,B> extends Father<T1,String>{
    @Override
    void test(String arg) {
        // TODO Auto-generated method stub        
    }    
}

//④完全保留,泛型子类
class Son4<T1,T2> extends Father<T1,T2>{
    @Override
    void test(T2 arg) {
        // TODO Auto-generated method stub        
    }    
}
class Son44<T1,T2,A,B> extends Father<T1,T2>{
    @Override
    void test(T2 arg) {
        // TODO Auto-generated method stub        
    }    
}

5、泛型擦除(使用、实现、继承的时候不指定类型)

public class App 
{
    public static void main( String[] args )
    {
        //第一种情况(泛型的擦除)
        Teacher teacheer = new Teacher();
        Object obj = teacheer.getName();
        //第二种情况(泛型的擦除)
        Teacher<String> teacher2 = new Teacher();
        //第三种情况(泛型的擦除)
        Teacher teacher3 = new Teacher<String>();
        //第四种情况,这种情况是有错误的(编译时错误)
        //Teacher<Object> teacher4 = new Teacher();
        //Teacher<String> teacher5 = teacher4;
    }
}
//泛型的擦除,使用、实现、继承不指定类型
class Teacher<T>{
    T name;
    T getName() {
        return name;
    }
    void setName(T name) {
        this.name = name;
    }
}

 6、泛型的嵌套

public class Solution {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Student<Double> s1 = new Student<Double>();
        s1.setScore((double) 100);
        Banji<Student<Double>> ssas = new Banji<Student<Double>>();
        ssas.setStu(s1);
        Double adasd = ssas.getStu().getScore();
        System.out.println(adasd);
    }

}

class Student<T> {
    T score;

    public T getScore() {
        return score;
    }

    public void setScore(T score) {
        this.score = score;
    }

}

class Banji<R> {
    R stu;

    public R getStu() {
        return stu;
    }

    public void setStu(R stu) {
        this.stu = stu;
    }

}

7、泛型需要注意的地方

①泛型没有多态
②泛型没有数组
③泛型不能使用静态属性
④泛型不能使用基本数据类型

⑤静态方法中不能访问类的泛型

⑥catch语句中不能使用泛型catch(T e){}这样子是错误的

public class DuoTai {

    public static void main(String[] args) {
        //泛型没有多态
        Object object = new String();
     Object[] strs = new String[10];//数组是可以的
//List<Object> object1 = new ArrayList<String>();错误 //泛型没有数组 //List<Object>[] object2 = new ArrayList<Object>[10];错误 //jdk1.7关于泛型的简化 List<Object> object3 = new ArrayList<>(); //相较于以前的List<Object> object3 = new ArrayList<Object>(); } } class Fruit { } class Apple extends Fruit { } class Pear extends Fruit { } class FushiApple extends Apple { }

二、JAVA的泛型通配符:?(super和extends)

List<?>是所有List<Object>,List<String>,List<Integer>...的父类

List<?>这样的集合是可以读取的(读取出来的元素类型是Object),写入是不允许的,只能写入null(这个要结合这种式子只能写在等号左边,它不知道等号右边传给它的实际的集合是什么类型的)

1、泛型通配符(?)

①?通配符就是表示类型不确定

②只能用在(声明类型、方法参数)上也就是等号左边;不能用在定义泛型类上也就是等号右边

③不能用在定义泛型类泛型接口泛型方法上(就是不能放在定义泛型的尖括号里面)

List<?> list = new ArrayList<String>();
list = new ArrayList<Integer>();
list = new ArrayList<Date>();

2、泛型上限(? extends  xxx)(包含等于)

①一般用于限制某个操作
②不能使用在数据添加上面,一般用于数据读取

③List<?>等同于List<? extends Object>

public class App 
{
    public static void main( String[] args )
    {
        List<? extends Fruit> t1 = new ArrayList<Fruit>();
        test(t1);
        List<Fruit> t2 = new ArrayList<Fruit>();
        test(t2);
        List<Apple> t3 = new ArrayList<Apple>();
        test(t3);
        List<? extends Apple> t4 = new ArrayList<FushiApple>();
        test(t4);
        List<?> t5 = new ArrayList<Fruit>();
        //List<?>等同于List<? extends Object>
        //test(t5);错误
        
    }
    static void test(List<? extends Fruit> list) {
        //list.add(new Apple());错误
        list.add(null);
    }
    
}
class Fruit{
    
}
class Apple extends Fruit{
    
}
class Pear extends Fruit{
    
}
class FushiApple extends Apple{
    
}
class Test<T extends Fruit>{
    
}

3、泛型下限(? super  xxx)(包含等于)

①不能用于添加父类信息

public class App {
    public static void main(String[] args) {
        List<Fruit> t1 = new ArrayList<Fruit>();
        show(t1);
        List<Apple> t2 = new ArrayList<Apple>();
        show(t2);
        List<Object> t3 = new ArrayList<Object>();
        show(t3);
        List<? super Apple> t4 = new ArrayList<Apple>();
        show(t4);
        List<? super Fruit> t5 = new ArrayList<Object>();
        show(t5);
        List<? super FushiApple> t6 = new ArrayList<Object>();
        //show(t6);错误
        List<?> list7 = new ArrayList<Object>();
        //show(t7);错误
    }

    static void show(List<? super Apple> list) {
        list.add(new Apple());
        list.add(new FushiApple());
        // 不能用于添加父类信息
        //list.add(new Fruit());
    }
}

class Fruit {

}

class Apple extends Fruit {

}

class Pear extends Fruit {

}

class FushiApple extends Apple {

}

4、图解

假设给定的泛型类型为G,(如List<E>中的List),两个具体的泛型参数X、Y,当中Y是X的子类:

  • G<? extends Y> 是 G<? extends X>的子类型(如List<? extends Cat> 是 List<? extends Animal>的子类型)。
  • G<X> 是 G<? extends X>的子类型(如List<Animal> 是 List<? extends Animal>的子类型)
  • G<?> 与 G<? extends Object>等同,如List<?> 与List<? extends Objext>等同。

 Plate<? extends Fruit>Plate<Fruit>以及Plate<Apple>的基类。这种不能往里面存,只能取。

Plate<? super Fruit>Plate<Fruit>的基类,但不是Plate<Apple>的基类。这种只能往里面存,不能取。要取也只能取在Object对象里。

三、一个经典的实例:

package org.eclipse.winery.repository;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Main2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Obj> list = new ArrayList<Obj>();
        list.add(new Obj());
        List<?> list2 = list;
        list2.forEach((obj) -> System.out.println(((Obj) obj).name));
        Collection<?> list3 = list;
        list3.forEach((obj) -> System.out.println(((Obj) obj).name));
        Collection<Obj> list4 = list;
        list4.forEach((obj) -> System.out.println(((Obj) obj).name));

    }

    private static class Obj {
        public String name = "Soar up into the sky with one start!";
    }
}

从这里我们看出了Collection<Obj>是List<Obj>的父类

四、泛型的静态方法

静态方法有一种情况需要注意一下,那就是在类中的静态方法使用泛型:静态方法无法访问类上定义的泛型;如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。

即:如果静态方法要使用泛型的话,必须将静态方法也定义成泛型方法 。

五、JAVA的extends在泛型中的扩展

public static <T extends Comparable<T>> void sort(T[] arr) {
        
    }
原文地址:https://www.cnblogs.com/erdanyang/p/10304215.html