1.Java泛型指南-泛型的定义

Java泛型指南

泛型的由来

简介

Java泛型(Generic)是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

官方说明:

When you take an element out of a Collection, you must cast it to the type of element that is stored in the collection. Besides being inconvenient, this is unsafe. The compiler does not check that your cast is the same as the collection’s type, so the cast can fail at run time.

Generics provides a way for you to communicate the type of a collection to the compiler, so that it can be checked. Once the compiler knows the element type of the collection, the compiler can check that you have used the collection consistently and can insert the correct casts on values being taken out of the collection.

参照:https://docs.oracle.com/javase/1.5.0/docs/guide/language/generics.html

官网查找路径:

https://www.oracle.com/cn/java/technologies/java-se-api-doc.html

jdk程序员指南-5.0英文版:https://docs.oracle.com/javase/1.5.0/docs/

New Features and Enhancements:https://docs.oracle.com/javase/1.5.0/docs/relnotes/features.html#generics

Generics:https://docs.oracle.com/javase/1.5.0/docs/guide/language/generics.html

为什么要使用泛型程序设计

泛型程序设计(Generic programming)意味着编写的代码可以被很多不同类型的对象所重用。

存在问题

  • 编译期间没有代码检查
  • 调用期间发现转换异常

泛型的演变过程

jdk5以前没有泛型的情况
package com.naixue.vip.p6.before5;

import java.io.File;

/**
 * @Description 模拟JDK5以前的没有泛型之前对象重用的问题
 * @Author xh 
 * @Date 2020/7/6 3:04 PM
 **/
public class ArrayList {

    private int size = 0;

    private Object[] elements = {};

    public Object get(int i) {
        if (size > i) {
            return elements[i];
        }
        throw new IndexOutOfBoundsException();
    }

    public void add(Object o) {
        size++;
        Object[] array = new Object[size];
        for (int i = 0; i < elements.length; i++) {
            array[i]=elements[i];
        }
        array[size-1]=o;
        elements=array;
    }

    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(1);
        arrayList.add("a");
        // 这里没有错误检查。可以向数组列表中添加任何类的对象
        arrayList.add(new File("/"));

        //对于这个调用,编译和运行都不会出错。然而在其他地方,如果将get的结果强制类型转换为String类型,就会产生一个错误
        String file=(String)arrayList.get(2);
    }
}
使用泛型后
package com.naixue.vip.p6.evolution;

/**
 * @Description 模拟JDK5以前的没有泛型之前对象重用的问题
 * @Author xh 
 * @Date 2020/7/6 3:04 PM
 **/
public class ArrayListNew<E> {

    private int size = 0;

    private Object[] elements = {};

    public Object get(int i) {
        if (size > i) {
            return elements[i];
        }
        throw new IndexOutOfBoundsException();
    }

    public void add(E o) {
        size++;
        Object[] array = new Object[size];
        for (int i = 0; i < elements.length; i++) {
            array[i]=elements[i];
        }
        array[size-1]=o;
        elements=array;
    }

    public static void main(String[] args) {
        ArrayListNew<String> arrayList = new ArrayListNew<String>();
        arrayList.add("a");
        String s=(String)arrayList.get(0);
        //演示时放开注释
//        arrayList.add(1);
//        // 编译不通过,不会导致运行后才发生错误
//        arrayList.add(new File("/"));
//        String file=(String)arrayList.get(2);
    }
}

泛型的可重用性

package com.naixue.vip.p6.feature;

import org.junit.Test;

import static junit.framework.TestCase.assertTrue;

/**
 * @Description 体现泛型的代码可重用性
 * @Author xh 
 * @Date 2020/7/6 3:04 PM
 **/
public class Reuse<T extends Comparable>
{
    public Integer compareTo(T t1, T t2) {
        return t1.compareTo(t2);
    }

    @Test
    public void testByGenericT()
    {
        Integer n1=1;
        Integer n2=2;
        Reuse<Integer> integerReuse =new Reuse<Integer>();
        assertTrue(integerReuse.compareTo(n1,n2) == -1);

        String s1="100";
        String s2="201";
        Reuse<String> integerReuse2 =new Reuse<String>();
        assertTrue(integerReuse2.compareTo(s1,s2) == -1);
    }
}

泛型的类型

泛型类

泛型类(generic class)就是具有一个或多个类型变量的类

public class Pair<T> {
    private T first;
    private T second;
    public Pair() { first = null; second = null}
    public Pair(T first, T second) {
        this.first = first;
        this.second = second;
    }
    public T getFirst() { return first; }
    public T getSecond() { return second; }
    public void setFirst(T newValue) { first = newValue; }
    public void setSecond(T newValue) { second = newValue; }
}

泛型方法

package com.naixue.vip.p6.funciton;

/**
 * @Description 泛型方法的使用
 * @Author xh 
 * @Date 2020/7/6 17:58
 **/
public class ArrayAlg {

    public static <T> T getMiddle(T... a) {
        return a[a.length / 2];
    }

    public static void main(String[] args) {
        String middle =ArrayAlg.<String>getMiddle("a","b","c");
        System.out.println(middle);
        //因为有两种方式处理。所有的都自动装箱,则得到 两个 Integer 和一个Double
        // 之后寻找公共超类 Number 和公共接口 Comparable 于是编译器不知道该如何处理了。
//        Integer n =ArrayAlg.<Integer>getMiddle(1,2,3.2);
//        System.out.println(n);
    }
}

子类泛型

class<T extends 父类>

package com.xh.java.wildcard;

import com.xh.java.classes.Pair;
import com.xh.java.vo.Man;
import com.xh.java.vo.Parson;
import com.xh.java.vo.Woman;

/**
 * @Description 泛型类型限定只能使用子类
 * @Author xh 
 * @Date 2020/7/6 19:56
 **/
public class Programmer<T extends Parson> {

    public <T extends Parson> Pair<T> youngAndOld(T[] a) {
        if(a == null || a.length == 0) {
            return null;
        }
        T min = a[0];
        T max = a[1];
        for(int i = 0; i < a.length; i++) {
            if(min.getAge().compareTo(a[i].getAge()) > 0) {
                min = a[i];
            }
            if(max.getAge().compareTo(a[i].getAge()) < 0) {
                max = a[i];
            }
        }
        return new Pair<>(min, max);
    }

    public static void main(String[] args) {
        Programmer<Parson> programmer = new Programmer<Parson>();
        Man man=new Man("陈先生",48,"劳力士","幻影");
        Woman woman=new Woman("刘女士",27,"LV","迪奥");
        Man man1=new Man("张先生",32,"浪琴","奥迪");
        Woman woman1=new Woman("吴女士",18,"LV","圣罗兰");
        Parson[] parsons=new Parson[4];
        parsons[0]=man;
        parsons[1]=woman;
        parsons[2]=man1;
        parsons[3]=woman1;

        Pair<Parson> parsonPair = programmer.youngAndOld(parsons);

        //子类型规则,即任何参数化的类型是原生态类型的一个子类型,
        //Programmer<T>是Programmer<Parson>类型的一个子类型,而不是Programmer<Object>的子类型。
//        Programmer<String> programmer1 = new Programmer<String>();
//        Programmer<Object> programmer1 = new Programmer<Object>();
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xianghan收藏册

极简精品作,一分也是一份鼓励哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值