Java基础复习-泛型

本文是Java学习查缺补漏,聚焦泛型。介绍了使用泛型和自定义泛型,包括自定义泛型类、接口和方法的规则,如泛型参数放置、构造器写法、实例化要求等,还提及泛型在继承、通配符使用等方面的体现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java基础复习-泛型

本文仅对java学习过程的查缺补漏

使用泛型

自定义泛型

  • 可以自定义泛型类、接口;方法

  • 泛型类可能有多个参数,此时应将多个参数一起放在尖括号内,比如:<T,E,V>

  • 泛型类的构造器如下:public GenericClass(){};而不是下面这种:public GenericClass<E>(){}

  • 实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致

  • 泛型不同的引用不能相互赋值

    • 尽管在编译时,ArrayList<String>ArrayList<Integer>是两种类型,但是,在运行时只有一个ArrayList被加载到JVM
  • 泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。要用泛型则一直都用泛型,不用则一直不用

  • 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象

  • jdk1.7,泛型的简化操作:ArrayList<Fruit> list = new ArrayList<>();

  • 泛型的指定不能使用基本数据类型,可以使用包装类替换

  • 在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但是在静态方法中不能使用类的泛型。

  • 泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的,并非在实例化类时确定的

  • 异常类不能是泛型的

  • 不能使用new E[],但是可以E[] elements = (E[])new Object[capacity];

  • 父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型

  • 泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。即:泛型方法所属的类是不是泛型类都没有关系

    • public <E> List<E> copyFromArrayToList(E[] arr){
          ArrayList<E> list = new ArrayList<>();
          
          for(E e : arr){
              list.add(e);
          }
          return list;
      }
      
  • 泛型在继承方面的体现

    • 虽然类A是类B的父类,但是G<A>G<B>二者不具备子父类关系,二者是并列关系。
    • 补充:类A是类B的父类,A<G>B<G>的父类
  • 通配符的使用

    • 类A是类B的父类,G<A>G<B>是没有关系的,二者共同的父类是:G<?>

    • 需要注意的一点:对于List<?>就不能向其内部添加任何数据(除了null),只能读不能写

    • @Test
      public void test3(){
          List<Object> list1 = null;
          List<String> list2 = null;
          List<?> list = null;
      
          list = list1;
          list = l
              ist2;
      }
      
    • ? extend A>:即<=`

      • G<? extend A>可以作为G<A>G<B>的父类,其中B是A的
    • ? super A>:即>=`

      • G<? super A>可以作为G<A>G<B>的父类,其中B是A的
      • 子类可以赋给父类,但是父类不能赋给子类
    • class Student1 extends Person{}
      
      @Test
      public void test4(){
          List<? extends Person> list1 = null;    //  <=
          List<? super Person> list2 = null;      //  >=
      
          List<Student1> list3 = null;
          List<Person> list4 = null;
          List<Object> list5 = null;
      
          //list1可以作为list3和list4的父类
          list1 = list3;
          list1 = list4;
          //        list1 = list5;    错的
      
          //list2可以作为list4和list5的父类
          //        list2 = list3;    错的
          list2 = list4;
          list2 = list5;
      
          //读取数据:
          list1 = list3;
          //这里可以用Person或者Object来接收,因为? extends Person的意思是:
          //Person类或者Person的子类,子类的子类...
          //那么就多态而言,需要是Person,或者Person的父类才能接收子类对象
          //看的是? extend Person,这里的Person,和new出来的无关
          Person person = list1.get(0);
          Object obj = list1.get(0);
      
          list2 = list4;
          //这里只能用Object的对象接收,因为? super Person表示的是:
          // 至少要填的是Person,或者Person的父类,父类的父类...,
          // 那么如果声明的类型比?的类型小,就不能满足多态,所以只能用Object接收
          //因为Object是所有类的父类,最差也是它本身
          //看的是? extend Person,这里的Person,和new出来的无关
          Object object = list2.get(0);
      
          //写入数据
          //子类可以赋给父类,但是父类不能赋给子类
          //        list1.add(new Student1());    //?比Person小或等于Person,但是不知道小多少,也许比Student还小
          list2.add(new Person());        //?比Person大或等于Person,所以只要比Person小都可以,Object也不行,可能比Object还大
          list2.add(new Student1());
      }
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值