Java泛型

1. 泛型

1.1 泛型的理解

泛型的好处:
1) 编译时,检查添加元素的类型,提高了安全性
2) 减少了类型转换的次数,提高效率
不使用泛型
Dog -加入-> Object-取出-> Dog //放入到ArrayList 会先转成Object,在取出时,还需要转换成Dog使用泛型
Dog-> Dog -> Dog1/放入时,和取出时,不需要类型转换,提高效率
3) 不再提示编译警告

泛型介绍:
int a= 10;
理解: 泛(广泛)型(类型) => Integer,String,Dog
1) 泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题
2) 在类声明或实例化时只要指定好需要的具体的类型即可。
3) Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。同时,代码更加简洁、健壮
4) 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方
法的返回值的类型,或者是参数类型。

package com.zakedu.generic;
 import java.util.List;
 /**
 *@author
*@version1.0
 */
 public class Generic03{
 public static void main(String[]args){
 //注意,特别强调:E具体的数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
    Person<String> person =new Person<String>("zak");
     person.show();//String
 /*
你可以这样理解,上面的Person类
class Person {
 String s ;//E 表示 s 的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
 public Person(String s) {//E 也可以是参数类型
    this.s = s;
 }
 public String f() {//返回类型使用 E
 return s;
 } }
*/
 Person<Integer> person2 = new Person<Integer>(100);
     person2.show();//Integer
 /*
    class Person {
     Integer s ;//E 表示 s 的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
    public Person(Integer s) {//E 也可以是参数类型
        this.s = s;
 }
    public Integer f() {//返回类型使用 E
     return s;
 } }
 */
 } }
 //泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,
// 或者是某个方法的返回值的类型,或者是参数类型
    class Person<E> {
    E s ;//E 表示 s的数据类型, 该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
 public Person(E s) {//E 也可以是参数类型
    this.s = s;
 }
 public E f() {//返回类型使用E
     return s;
 }

public void show() {
 System.out.println(s.getClass());//显示 s 的运行类型
} }

1.2 泛型的语法

泛型的声明:

泛型的实例化:
要在类名后面指定类型参数的值(类型)。如:
1)  List<String> strList = new ArrayList<String>0;
2)   Iterator<Customer> iterator = customers.iterator();

泛型使用举例:
举例说明,泛型在 HashSet,HashMap的使用情况,
1.创建3个学生对象        2. 放入到HashSet中学生对象,使用.        3. 放入到HashMap中,要求
Key 是String name. Value就是学生对象        4. 使用两种方式遍历

package com.zakedu.generic;
 import java.util.*;
/**
 * @author 
* @version 1.0
 */
 @SuppressWarnings({"all"})
 public class GenericExercise {
     public static void main(String[] args) {
     //使用泛型方式给HashSet 放入3个学生对象
        HashSet<Student> students = new HashSet<Student>();
         students.add(new Student("jack", 18));
         students.add(new Student("tom", 28));
         students.add(new Student("mary", 19));

         //遍历
        for (Student student : students) {
         System.out.println(student);
     }
     //使用泛型方式给HashMap 放入3个学生对象
    //K-> String V->Student
     /*
     HashMap<String, Student> hm = new HashMap<String, Student>();
     public class HashMap<K,V> {}
     */
     hm.put("milan", new Student("milan", 38));
     hm.put("smith", new Student("smith", 48));

    hm.put("hsp", new Student("hsp", 28));
     //迭代器 EntrySet
     /*
     public Set<Map.Entry<K,V>> entrySet() {
     Set<Map.Entry<K,V>> es;
     return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
     }
     */

     Set<Map.Entry<String, Student>> entries = hm.entrySet();
 /*
     public final Iterator<Map.Entry<K,V>> iterator() {
     return new EntryIterator();
     }
 */
     Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
     System.out.println("==============================");
     while (iterator.hasNext()) {
     Map.Entry<String, Student> next = iterator.next();
     System.out.println(next.getKey() + "-" + next.getValue())
    } } }
 /**
* 创建 3个学生对象
* 放入到HashSet中学生对象, 使用.
 * 放入到 HashMap中,要求 Key 是 Stringname,Value 就是 学生对象
* 使用两种方式遍历
*/
 class Student {
 private String name;
 private int age;
 public Student(String name, int age) {
 this.name = name;
 this.age = 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;
 }
 @Override
 public String toString() {
 return "Student{" +
 "name='" + name + '\' +
 ", age=" + age +
 '}';
 } }

1.3 泛型使用的注意事项

 package com.zakedu.generic;
 import java.util.ArrayList;
 import java.util.List;
 /**
 * @author 
* @version 1.0
 */
 @SuppressWarnings({"all"})
 public class GenericDetail {
     public static void main(String[] args) {
     //1.给泛型指向数据类型是,要求是引用类型,不能是基本数据类型
    List<Integer> list = new ArrayList<Integer>(); //OK
     //List<int> list2 = new ArrayList<int>();//错误
    //2. 说明
    //因为 E 指定了 A 类型, 构造器传入了 newA()
     //在给泛型指定具体类型后,可以传入该类型或者其子类类型
    Pig<A> aPig = new Pig<A>(newA());
     aPig.f();
     Pig<A> aPig2 = new Pig<A>(new B());
     aPig2.f();
     //3. 泛型的使用形式
    ArrayList<Integer> list1 = new ArrayList<Integer>();
     List<Integer> list2 = new ArrayList<Integer>();
     //在实际开发中,我们往往简写
    //编译器会进行类型推断, 老师推荐使用下面写法
    ArrayList<Integer> list3 = new ArrayList<>();
     List<Integer> list4 = new ArrayList<>();
     ArrayList<Pig> pigs = newArrayList<>();
     //4. 如果是这样写 泛型默认是 Object
     ArrayList arrayList = new ArrayList();//等价 ArrayList<Object> arrayList = new ArrayList<Object>();
 /*
 public boolean add(Object e) {
 ensureCapacityInternal(size + 1); // Increments modCount!!
 elementData[size++] = e;
 return true;
 }
*/
     Tiger tiger = new Tiger();
 /*
     class Tiger {//类
    Object e;
     public Tiger() {}
     public Tiger(Object e) {
     this.e = e;
     } }
*/
 } }
    class Tiger<E> {//类
        E e;
     public Tiger() {}
     public Tiger(E e) {
     this.e = e;
 } }
 class A{}
     class B extends A{}
     class Pig<E> {//
     E e;
 public Pig(E e) {
     this.e = e;
 }
 public void f() {
    System.out.println(e.getClass());//运行类型
} }

1.4 自定义泛型

基本语法:

案例:

 package com.zakedu.customgeneric;
 import java.util.Arrays;
 /**
 *@author
*@version1.0
 */
 @SuppressWarnings({"all"})
public class CustomGeneric_ {
     public static void main(String[] args) {
     //T=Double, R=String, M=Integer
     Tiger<Double,String,Integer> g = new Tiger<>("john");
     g.setT(10.9); //OK
     //g.setT("yy"); //错误,类型不对
    System.out.println(g);
     Tiger g2 = new Tiger("john~~");//OK T=Object R=Object M=Object
     g2.setT("yy"); //OK ,因为 T=Object "yy"=String 是 Object 子类
    System.out.println("g2=" + g2);
 } }

//解读
//1. Tiger 后面泛型,所以我们把 Tiger 就称为自定义泛型类
//2, T, R, M 泛型的标识符, 一般是单个大写字母
//3. 泛型标识符可以有多个.
 //4. 普通成员可以使用泛型 (属性、方法)
 //5. 使用泛型的数组,不能初始化
//6. 静态方法中不能使用类的泛型
    class Tiger<T, R, M> {
         String name;
         Rr; //属性使用到泛型
         Mm;
        Tt;
 //因为数组在new 不能确定T的类型,就无法在内存开空间
        T[] ts;
 public Tiger(String name) {
     this.name = name;
 }
 public Tiger(R r, M m, T t) {//构造器使用泛型
    this.r = r;
     this.m = m;
     this.t = t;
 }
 public Tiger(String name, R r, M m, T t) {//构造器使用泛型
     this.name = name;
     this.r = r;
     this.m = m;
     this.t = t;
 }
 //因为静态是和类相关的,在类加载时,对象还没有创建
//所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化
 // static R r2;
 // public static void m1(M m) {
 // }
 //方法使用泛型
public String getName() {
     return name;
 }
 public void setName(String name) {
     this.name = name;
 }
 public R getR() {
     return r;
 }
 public void setR(R r) {//方法使用到泛型
    this.r = r;
 }
 public M getM() {//返回类型可以使用泛型.
     return m;
 }
 public void setM(M m) 
    this.m = m;
 }
 public T getT() {
     return t;
 }
 public void setT(T t) {
     this.t = t;
 }
 @Override
 public String toString() {
     return "Tiger{" +"name='" + name + '\' +
     ", r=" + r +
     ", m=" + m+
     ", t=" + t +
     ", ts=" + Arrays.toString(ts) +
     '}';
 } }

1.4.1 自定义泛型接口

基本语法:

1.4.2 自定义泛型方法

1.5 泛型的继承和通配符

1) 泛型不具备继承性
        List<Object> list = new ArrayList<String>(); // 对吗?
2) <?>:支持任意泛型类型
3) <? extends A>:支持A类以及A类的子类,规定了泛型的上限
4) <? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

1.6 JUnit

1.6.1 为什么需要JUnit

1.6.2 基本介绍

1. JUnit是一个Java语言的单元测试框架
2. 多数Java的开发环境都已经集成了JUnit作为单元测试的工具

1.6.3 使用步骤

 package com.zakedu.junit_;
 import org.junit.jupiter.api.Test;
 /**
 *@author
*@version1.0
 */
 publicclassJUnit_{
     publicstaticvoidmain(String[]args){
     //传统方式
    //newJUnit_().m1();
     //newJUnit_().m2();
 }
  @Test
  publicvoidm1(){
     System.out.println("m1方法被调用");
 }
 @Test
 publicvoidm2(){
     System.out.println("m2方法被调用");
 }
 @Test
 publicvoidm3(){
     System.out.println("m3方法被调用");
 } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值