zoukankan      html  css  js  c++  java
  • 泛型

    泛型:

    是种未知的数据类型,当我们不知道使用什么数据类型的时候可以使用泛型,泛型也可以看出是一个变量用来接收数据类型。

    E e: Element元素

    Tt Type类型

    ArrayList集合在定义的时候不知道集合中都会存储什么类型的数据,所以类型使用泛

    型E未知的数据类型。

    1.泛型的好处

    创建集合对象,不用泛型

    好处:

    • 默认Object类型,可以存储任意类型的数据

    弊端:

    • 不安全,可能会导致类型转换异常。ClassCastException

      调用子类特有的方法,向下转型 String s=(String)next; System.out.println(s.length());

      Integer类型无法转换为String类型

    package setclass.Collection;

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;

    public class TestDemo {
      public static void main(String[] args) {
          ArrayList list=new ArrayList();
          list.add("张三");
          list.add(1);
          list.add(true);
          Iterator it = list.iterator();
          while (it.hasNext()){
              Object next = it.next();
              System.out.println(next);
              //调用子类特有的方法,向下转型
              String s=(String)next;
              System.out.println(s.length());
          }
      }
    }

    创建集合对象,使用泛型

    好处:

    • 避免类型转换异常的麻烦,可以存储设什么类型的数据就取出什么类型

    • 将运行期异常提升到编译期类型

    弊端:

    • 只能存储一种类型

    private static void demo2() {
      ArrayList<String> list=new ArrayList<>();
      list.add("张三");
      list.add("李四");
      list.add("王五");
      Iterator<String> it = list.iterator();
      while (it.hasNext()){
          String next = it.next();
          System.out.println(next);
          System.out.println(next.length());
      }
    }

    2.定义和使用含有泛型的类

    含有泛型的类:

    • 泛型类,模拟ArrayList集合

    • 泛型可以接受未知的数据类型,创建对象时确定泛型数据类型

    package setclass.Genericdemo;

    public class GenericClassDemo<E> {//泛型类,模拟ArrayList集合
          //泛型可以接受未知的数据类型,创建对象时确定泛型数据类型
      private E name;//E 表示未知数据类型

      public E getName() {
          return name;
      }

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

    测试类:

    • 默认Object类型

      GenericClassDemo gcd = new GenericClassDemo();
    • 泛型使用String类型

      GenericClassDemo< String > gc = new GenericClassDemo<>();
    • 泛型使用Integer类型

      GenericClassDemo< Integer > gc1 = new GenericClassDemo<>();
    package setclass.Genericdemo;

    public class GenericTestDemo1 {//测试类

      public static void main(String[] args) {
          //默认Object类型
          GenericClassDemo gcd = new GenericClassDemo();
          //泛型使用String类型
          GenericClassDemo<String> gc = new GenericClassDemo<>();
          gc.setName("张三");
          System.out.println(gc.getName());
          //泛型使用Integer类型
          GenericClassDemo<Integer> gc1 = new GenericClassDemo<>();
          gc1.setName(100);
          System.out.println(gc1.getName());
       
      }
    }

    3.定义含有泛型的方法

    格式:

    修饰符 泛型 返回值类型 方法名(参数列表){

    方法体

    }

    传递什么类型的数据,泛型就是什么数据。 也可以定义含有泛型的静态方法。

    package setclass.Genericdemo;

    public class GenericMethod {//含有泛型的测试方法
      public <E> void gcMethod(E e){
          System.out.println(e);
      }
    }

    测试:

    GenericMethod gc = new GenericMethod();
    gc.gcMethod(10);
    运行结果:
    10

    4.含有泛型的接口

    一种在实现接口时,确定泛型的类型;

    另一种是在创建对象时,确定泛型的类型。

    4.1第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型

    迭代器接口:

    public interface Iterator< E> {

    E next();

    Scanner类实现了Iterator接口,并指定接口的泛型为String,所以重写的next方法泛型默认就是String

    public final class Scanner implements Iterator< String>{

    public String next() { }

    }

    泛型接口:

    public interface GenericInterface<I> { //定义泛型接口
    void method(I i);//抽象方法 method,默认public abstract
    }

    通过实现类,实现接口,指定接口的泛型:

    public class GenericInterfaceImp1 implements GenericInterface<String>{//定义实现类
    //通过实现接口,指定接口的泛型
    @Override
    public void method(String s) {
    System.out.println(s);
    }


    }

    测试类

    public class GenericInterfaceTestDemo {
    public static void main(String[] args) {//测试含有泛型的接口
    GenericInterfaceImp1 gci1 = new GenericInterfaceImp1();
    gci1.method("潜龙");
    }
    }
    潜龙
    4.2第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走

    就相当于定义了一一个含有泛型的类,创建对象的时候确定泛型的类型

    public interface List< E>{ boolean add(E e); E get(int index); }

    ArrList实现List接口:

    public class Arraylist< E> implements list< E>{ public boolean add(E e) {} public E get(int index) {} }

    接口使用什么泛型,实现类就使用什么泛型,类跟着接口走:

    public class GenericInterfaceImp2<I> implements GenericInterface<I>{
    @Override
    public void method(I i) {
    System.out.println(i);
    }
    }

    测试类

    public class GenericInterfaceTestDemo {
    public static void main(String[] args) {//测试含有泛型的接口
    GenericInterfaceImp2<String> gci2 = new GenericInterfaceImp2<>();
    gci2.method("张三");
    GenericInterfaceImp2<Integer> gci21 = new GenericInterfaceImp2<>();
    gci21.method(123);
    }
    }
    运行结果:
    潜龙
    张三
    123

    5.泛型的通配符

    泛型的通配符:

    ?:代表任意的数据类型

    使用方式:

    • 不能创建对象使用

    • 只能作为方法的参数使用

    遍历含有多个数据类型的集合时,用含有泛型通配符的参数的方法遍历,使用迭代器遍历,迭代器返回的为Object类型的数据。

    • 泛型没有继承概念。

    package setclass.Genericdemo;

    import java.util.ArrayList;
    import java.util.Iterator;

    public class Demo1Generic {//泛型通配符
    public static void main(String[] args) {
    ArrayList<Integer> list1 = new ArrayList<>();
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list1.add(4);
    ArrayList<String> list2=new ArrayList<>();
    list2.add("zhangsan");
    list2.add("刘四");
    list2.add("张三");
    printArray(list1);
    printArray(list2);
    }
    public static void printArray(ArrayList<?> list){
    Iterator<?> it = list.iterator();
    while (it.hasNext()){
    Object next = it.next();
    System.out.println(next);
    }
    }
    }
    运行结果:
    1
    2
    3
    4
    zhangsan
    刘四
    张三
    泛型通配符高级使用
    • 泛型的上限限定: ? extends E

    代表使用的泛型只能是E类型的子类/本身

    • 泛型的下限限定: ? super E

    代表使用的泛型只能是E类型的父类/本身

     

    通过extends限制了通配符的上边界,也就是只接受Number及其子类类型。接口的实现和类的集成都可以通过extends来表示。

    而这里的Number也可以替换为T,表示该通配符所代表的类型是T类型的子类。

    public static void getData(List<? extends T> data) {
    System.out.println("data :" + data.get(0));
    }

    与上界通配符示对照也有下界通配符:

    public static void getData(List<? super Integer> data) {

    System.out.println("data :" + data.get(0));

    }

    下界通配符表示该通配符所代表的类型是T类型的父类。
  • 相关阅读:
    svmlight、libsvm 和 svmtorch(torch) 极夜.潜的日志 网易博客
    ObjectiveC学习之旅(二)函数、类、作用域
    快速掌握 ObjectiveC (For C/C++ developer)
    MAC系统使用总结
    VM虚拟机安装苹果雪豹操作系统
    asp.net调试遇到的问题
    C#调用WebService
    SqlServer2008建立触发器实例
    sqlserver2008无法登陆问题
    IIS上面部署网站
  • 原文地址:https://www.cnblogs.com/Hiramunderneath/p/15259212.html
Copyright © 2011-2022 走看看