java基础 ---- 泛型

java基础 ---- 泛型

泛型的理解概述:

  • 泛型是一种未知数据类型,可视为一种变量,用来接收具体的数据类型。
  • 在设计API时可以指定类,方法,接口支持泛型,那么使用API时会变得简洁,并在编译时期的得到语法检查。比如: 集合API源码申明了泛型,在使用集合API时确定泛型 “存什么,就取什么”清晰命明了,并且规避了将所有元素强制转型成单一类型可能出现的ClassCastException执行错误(见测试代码I)。

泛型的使用概述:

泛型可应用到的类、方法、接口中,将数据类型作为参数进行传递。

  • 定义类时,在类名后声明泛型,成员变量可使用泛型;使用类时,创建对象的同时确定泛型数据类型,类中所有用到泛型的地方随之确定。
  • 定义方法时,在方法的修饰符和返回值类型之间声明泛型,方法参数可使用泛型;使用方法时确定泛型,传入什么类型参数就是什么泛型。
  • 定义接口时,在接口名后声明泛型,方法参数,方法返回值可使用泛型;使用接口时,第一种方法是定义实现类的同时确定接口泛型,第二种方法是定义实现类的同时声明类含有泛型,接口与实现类的泛型一致,在创建对象的时候确定泛型数据类型。

集合中泛型通配符,泛型限定的测试代码:

/**运行前提:
 *1.IDEA提示下导入更多的包
 */

public class MyTest {
   
    public static void main(String[] args) {
        show1();
        show2();
        show3();
    }


    /** show1():不使用泛型与使用泛型对比
     * 分别创建不使用泛型,使用泛型的集合对象
     * 测试分别为两个集合添加元素
     * 分别为两个集合对象创建迭代器
     * 测试分别获取两个集合的元素
     * 测试分别获取两个集合字符串元素的字符数
     */
    public static void show1() {
        //1.
        //集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据
        ArrayList list = new ArrayList();
        list.add("abc");
        list.add(1);
        Iterator it = list.iterator();
        while (it.hasNext()) {
            //
            //取出元素也是Object类型
            Object obj = it.next();
            System.out.println(obj);
            //
            //使用String类特有的方法,length获取字符串的长度,需要向下转型
            String b = (String) obj; //会抛出ClassCastException类型转换异常,不能把Integer类型数据1转换为String类型
            System.out.println(b.length());
        }
        
        //2.
        //集合使用泛型,泛型是什么类型就只能存储什么类型的数据
        //JDK1.7版本之后,=号后边的泛型可以省略,后边的泛型可以根据前边的泛型推导出来
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("abc");
        //list.add(1); 错于存储与泛型不符的数据类型
        //
        //迭代器的泛型与集合保持一致
        Iterator<String> it2 = list2.iterator();
        while (it2.hasNext()) {
            //
            //取出元素也是String类型,所以可以直接调用length()方法
            String a = it2.next();
            System.out.println(a.length());
        }
    }


    /**show2()调用的方法:
     *定义一个能遍历所有泛型集合的方法
     */
    public static void printArray(ArrayList<?> list){//?代表任意泛型类型
        // public static void printArray(ArrayList<String> list)只能遍历<String>集合
        //  public static void printArray(ArrayList<Object> list)错于泛型没有继承概念
        // public static void printArray(ArrayList list)
        //
        Iterator<?> it = list.iterator();
        while(it.hasNext()){
            //it.next()方法,取出的元素是Object,可以接收任意的数据类型
            Object o = it.next();
            System.out.println(o);
        }
    }

/**show2():泛型通配符
 * 分别创建使用两种泛型的集合对象,并为集合添加元素
 * 测试调用方法遍历集合
 */
    public static void show2() {
        ArrayList<Integer> list01 = new ArrayList<>();
        ArrayList<?> list01 = new ArrayList<?>();//错于集合泛型只能集合作方法参数时使用,不能建立集合对象时使用
        list01.add(1);
        list01.add(2);

        ArrayList<String> list02 = new ArrayList<>();
        list02.add("a");
        list02.add("b");

        printArray(list01);
        printArray(list02);

    }

     /**show3()调用的方法:
      *分别用泛型上限,泛型下限定义方法
      */
     //参数含有泛型上下限定格式: 类名<? extends/super 上限泛型/下限泛型>对象名
     public static void getElement1(Collection<? extends Number> coll){}
     public static void getElement2(Collection<? super Number> coll){}
    /**show3():泛型限定
     *分别创建四种有继承关系的泛型集合对象
     * 测试四类对象分别调用两种泛型限定方法
     */
    public static void show3(){
        /*泛型继承关系:Integer extends Number extends Object
                       String extends Object*/
        Collection<Integer> list1 = new ArrayList<Integer>();
        Collection<String> list2 = new ArrayList<String>();
        Collection<Number> list3 = new ArrayList<Number>();
        Collection<Object> list4 = new ArrayList<Object>();
        //
        //getElement1参数泛型上限为Number,只能接受Number及其子类
        getElement1(list1);
        getElement1(list3);
        //getElement1(list2);错于String类和Number没有继承关系
        //getElement1(list4);错于Object类是Number的父类
        //
        //getElement1参数泛型下限为Number,只能接受Number及其父类
        getElement2(list3);
        getElement2(list4);
        //getElement2(list1);错于Integer类是Number类的下限
        //getElement2(list2);错于String类和Number类没有继承关系
    }

}

类,方法,接口声明泛型,使用泛型,确定泛型的测试代码:

/**
 * 定义一个泛型类,成员变量使用泛型
 */
class GenericClass<E> {
    private E name;

    public E getName() {
        return name;
    }

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

/**
 * 定义一个类,包含泛型方法,方法参数使用泛型
 */
class GenericMethod {
    //定义一个含有泛型的方法
    public <M> void method01(M m) {
        System.out.println(m);
    }

    //定义一个含有泛型的静态方法
    public static <S> void method02(S s) {
        System.out.println(s);
    }
}

/**
 * 定义一个泛型接口,包含泛型方法,方法参数使用泛型
 */
interface GenericInterface<I> {
    public abstract void method(I i);
}

public class MyTest {
    public static void main(String[] args) {
        show1();
        show2();
        show3();
    }
    /**
     * show1():测试含有泛型的类
     * 分别创建默认泛型为Object类型对象,泛型为Integer对象,String对象
     * 测试调用成员方法
     */
    public static void show1() {
        //不写泛型默认为Object类型
        GenericClass gc = new GenericClass();
        gc.setName(1);
        Object obj = gc.getName();

        //创建GenericClass对象,泛型使用Integer类型
        GenericClass<Integer> gc2 = new GenericClass<>();
        gc2.setName(1);
        Integer name = gc2.getName();
        System.out.println(name);

        //创建GenericClass对象,泛型使用String类型
        GenericClass<String> gc3 = new GenericClass<>();
        gc3.setName("小明");
        String name1 = gc3.getName();
        System.out.println(name1);
    }


    /**
     * show2():测试含有泛型的方法
     * 创建类的对象
     * 调用含有泛型的一般方法,含有泛型的静态方法
     */
    public static void show2() {
        //创建GenericMethod对象
        GenericMethod gm = new GenericMethod();

        //传递什么类型的参数,就是确定的什么泛型
        gm.method01(10);
        //gm.method01("abc");
        //gm.method01(8.8);
        //gm.method01(true);

        //静态方法,通过类名.方法名(参数)可以直接使用
        GenericMethod.method02("静态方法");
        //GenericMethod.method02(1);
        //gm.method02("静态方法"); 静态方法不建议创建对象使用
    }

    /**
     * show3():含有泛型接口的两种实现方式
     * 1.分别用两种方式定义接口实现类作MyTest内部类
     * 2.创建实现类对象
     * 调用重写方法
     */

    public static void show3() {
       //1. 
       //定义一个类实现接口,并确定接口
        class GenericInterfaceImpl1 implements GenericInterface<String> {
            @Override
            public void method(String s) {
                System.out.println(s);
            }
        }
        //
        //定义一个泛型类实现接口,不确定接口
        class GenericInterfaceImpl2<I> implements GenericInterface<I> {
            @Override
            public void method(I i) {
                System.out.println(i);
            }
            //
            //类的泛型与方法的泛型独立 
            public <S> void method2(S s) {
            }
        }

        //2.
        //第一种方式的实现类,使用时就不需要在声明
        GenericInterface gi = new GenericInterfaceImpl1();
        gi.method("AAA"); //AAA
        //
        //第二种方式的实现类,创建对象的同时声明接口泛型
        GenericInterface<Integer> GI = new GenericInterfaceImpl2<>();
        GI.method(1); //1
        GI.method2("abc"); //abc
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值