JAVA-泛型

JAVA—>泛型



泛型的引入

1.传统的方法中,不能对加入到集合中的数据类型进行约束(不安全)
2.遍历得到时候,需要类型转换,如果集合数据过多会对效率有影响

main方法:
ArrayList<Dog> arrayList = new ArrayList<Dog>();
   arrayList.add(new Dog("旺财",5));
   arrayList.add(new Dog("小白",3));
   arrayList.add(new Dog("小黑",7));
   //如果不小心加入一只猫
   //arrayList.add(new Cat("小花",6));
   System.out.println("-----使用泛型-----");
   for( Dog dog: arrayList){
   //遍历的时候可直接取出Dog 而不是 Object
      System.out.println(dog.getName()+"-"+dog.getAge());
   }

优点:
1.编译时,检查添加元素的类型,提高了安全性
2.减少类型转换的次数,提高了效率
3.不在提示编译警告


一、泛型(Generic)

1.定义:泛型,既广泛的类型 ( E->可以表示为Integer,String,Dog)
== 可以表示数据类型的类型==

2.又称参数化类型,jdk5.0出现的新特性,可以解决安全性问题

3.泛型可以保证如果程序在编译时没有发出警告,运行时也不会产生ClassException异常。同时代码简洁,健壮。

4.泛型作用是:可以在类声明时通过一个标识标识类中的某个属性的类型;或是某个方法的返回值类型,或是参数类型

Class Person<E> {
  E s; // E表示s的数据类型,定义时(编译)即确定是什么类型
  
public Person(E s){ //E也可以是参数类型
  this.s=s;
}

public E f(){ //E也可以是返回值类型
  return s;
   }
}

main方法:
Person<String> person =new Person<String>("msb");
//此时上方的E-->String类型
Person<Integer> person =new Person<Integer>(100);
//此时上方的E-->Integer类型

二、泛型的语法

1.泛型的声明

interface 接口名<T<T>>  / class 类名<K,V>{}

例如:List,ArrayList
其中,<>内代表类型,任意字母都可以

2.泛型的实例化

-要在类名后指定类型

List<String> strList =new ArrayList<String>();
Iterator<Customer> iterator =customers.iterator();

3.泛型的应用(举例)

package com.msbedu.generic;
import java.util.*;
public class generic01 {
    public static void main(String[] args) {
//1)创建三个学生对象,放入到HashSet中学生对象,遍历
        HashSet<Student> students = new HashSet<Student>();
        students.add(new Student("jack",18));
        students.add(new Student("lucy",19));
        students.add(new Student("mark",20));
        //遍历 --->增强for
        //这里声明了一个循环变量student,它的类型是Student
        // 表示每次循环都会从students集合中取出一个Student对象赋值给student变量。
        for(Student student:students){
            System.out.println(student);
        }

//2)放入到HashMap中,要求key是String name,value 是学生对象,遍历
        System.out.println("----------------------------------");
        HashMap<String, Student> hashMap = new HashMap<String, Student>();
        hashMap.put("jack",new Student("jack",18));
        hashMap.put("lucy",new Student("lucy",19));
        hashMap.put("mark",new Student("mark",20));
        //遍历---->迭代器 EntrySet
        Set<Map.Entry<String, Student>> entries = hashMap.entrySet();
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Student> next =  iterator.next();
            System.out.println(next.getKey()+"-"+next.getValue());
        }
    }
}

class Student{
    private  String name;
    private  int age;
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
*hashmap的遍历方法没有掌握*

四、泛型的使用细节和注意事项

1.E只能是引用类型(Integer),不能是基本数据类型

List<<Integer>Integer> list= new ArrayList<<Integer>Integer>();

2.在给泛型指定了具体类型后,可以传入该类型或其子类类型

main方法:
{
   Dog<A> dog1 = new Dog<A>(new A());
   Dog<A> dog2 = new Dog<A>(new B());
   //指定的是A类型 但是此时B是A的子类 所以B也可以传入
  }
    
class A{}
class B extends  A{}

class Dog<E>{
    E e;

    public Dog(E e) {
        this.e = e;
    }
}

3.书写泛型时后面<>内可以省略

List<Integer> list= new ArrayList<>(); 

4.不指定泛型的类型,默认为Object

List<Integer> list= new ArrayList<>(); 

五、自定义泛型

1.基本语法

class 类名<T,E…>{
成员
}

举例:
Class Person<E> {
  E s; // E表示s的数据类型,定义时(编译)即确定是什么类型
  
public Person(E s){ //E也可以是参数类型
  this.s=s;
}

public E f(){ //E也可以是返回值类型
  return s;
   }
}

2.使用细节

1).普通成员可以使用泛型(属性、方法)
2).使用泛型的数组,不能初始化
3).静态方法中不能使用类的泛型(静态属性也行)
4).泛型类中具体的类型,是在创建对象时确定的 <T,R…>
5).创建对象没有指定类型,默认Object

举例:
class Tiger<T>{
 1. T t; //属性使用泛型

    public Tiger(T t) { //构造器使用泛型
        this.t = t;
    }
    public T getT() { //返回值使用泛型
        return t;
    }
    public void setT(T t) { //方法使用泛型
        this.t = t;
    }
 2. T[] t=new T[8];×  //泛型数组不能初始化
    //因为数组在new不能确定T的类型,无法在内存开空间

 3. public static void m1(T t)  { //× 
    static T t;//×
   //因为静态与类相关,在类加载时,对象还没有创建(如果使用了泛型,JVM就无法完成初始化)
   }
}

六、自定义泛型接口

1.基本语法

Interface 接口名<T,R...>{}

2.使用细节

1.接口中,静态成员也不能使用泛型(与泛型类规定相同)
2.泛型接口的类型,在继承接口或者实现接口时确定
3.没有指定类型,默认为Object

Interface IUsb<U,R>{
1. U name="msb"; //接口中默认属性为 public static final
   U name;//×
   //普通方法,可以使用接口泛型
   R get(U u);
   void hi(R r){}
  
  }
2. interface IA extends IUsb<String,Double>{}
   class AA implements IA{} //×实现接口必须实现接口所有方法
   //实现后所有方法已经有具体的泛型
   
3. class BB implements IA<String,Integer>{}
   class CC implements IA{}//相当于默认为两个Obj0ect

七、自定义泛型方法

1.基本语法

修饰符<T,R...> 返回类型 方法名(参数){}

2.使用细节

1.泛型方法,可以定义在普通类,也可定义在泛型类中
2.当泛型方法被调用时,类型会确定
3.public void eat(E e){},修饰符后没<T,R…>
表示:该方法不是泛型方法,而是使用了泛型

Class car{
  public void run(){}//普通方法
  public <T> void fly(T t){}//泛型方法
}

八、泛型的继承和通配符

1.泛型的继承和通配符说明

1.泛型不具备继承性

Object o=new String("x"); //类有继承
LIst<Object> list = new ArrayList<String>();//×

2.<?>表示支持任意泛型类型
3.<?extends A>:支持A类以及的A类的子类,规定了泛型的上限
4.<? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

 //?extends 子类名AA:支持AA类以及AA的子类
 public static void printCollection1(List<? extends AA> c){
  for (Object obj :c){
  System.out.println(obj);
     }
  }
  
//?super 子类名AA:支持AA类以及AA的父类,不限于直接父类  
 public static void printCollection2(list<?  super AA> c){
  for (Object obj :c){
  System.out.println(obj);
     }
  }

   main方法:
   List<Object> list1=new ArrayList<>();
   List<AA> list2=new ArrayList<>();
List<BB>list3=new ArrayList<>();
List<CC> list4=new ArrayList<>():
   
  //如果是List<?> c,可以接受任意类型   
printCollection(list1);printCollection(list2);printCollection(list3);printCollection(list4);//如果是List<? extends AA> c,可以接受AA类以及AA的子类   
printCollection1(list1);  ×
printCollection1(list2);printCollection1(list3);printCollection1(list4);//如果是List<? super AA> c,可以接受AA类以及AA的父类,不限于直接父类   
printCollection2(list1);printCollection2(list2); ×
printCollection2(list3); ×
printCollection2(list4); ×

 class AA{}
 class BB extends AA{}
 class CC extends BB{} 

九、JUnit

1.介绍

1.JUnit是java的语言单元测试框架
2.多数java环境集成了JUnit作为单元测试的工具

2.演示

在需要测试的方法前加 @Test alt+enter-->add ‘JUnit5.4to classpath
自动导入包 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值