Java泛型

4.1泛型概述

泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
一提到参数,最熟悉的就是定义方法时有形参,,然后调用此方法时传递实参,那么参数化类型怎么理解呢?
顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。这种参数类型可以用在类、方法和接口中,分别称为泛型类、泛型方法、泛型接口。

泛型定义格式:
<类型>:指定一种类型的格式。这里的类型可以看成是形参。
<类型1,类型2>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参。
将来具体调用时给定的类型可以看成是实参,并且实参的类型只能是引用类型。

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

public class GenericDemo {
    public static void main(String[] args) {
        Collection c=new ArrayList();

        c.add("h");
        c.add("e");
        c.add("l");
        c.add("l");
        c.add("o");
        c.add(100);

        Iterator it=c.iterator();
        while (it.hasNext()){
            Object obj=it.next();
            System.out.println(obj);
        }
    }
}

泛型的好处:
1、把运行时期的问题提前到了编译期间
2、避免了强制类型转换

4.2泛型类

创建对象的时候传的是什么类型,就是什么类型。

package GenericDemo01;

public class Generic <T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}

import daily_collection.Student;

public class GenericDemo01 {
    public static void main(String[] args) {
        Student s=new Student();
        s.setName("ANNA");
        s.setAge(30);

        System.out.println(s.getName());

        Generic<String> g1=new Generic<String>();
        g1.setT("WON");
        System.out.println(g1.getT());
        Generic<Boolean> g2=new Generic<Boolean>();
        g2.setT(false);
        System.out.println(g2.getT());
    }
}

4.3泛型方法

泛型类:可以看到我们在创建对象的时候还是每次创建对象的时候需要声明类型,如果我们想在调用方法的时候传的什么对象就调用什么类型,那么我们可以使用泛型方法。

public class GenericMethod<T> {
    public void show(T t){
        System.out.println(t);
    }
}
public class GenericDemo02 {
    public static void main(String[] args) {
        GenericMethod<String> gm1=new GenericMethod<String>();
        gm1.show("ak");
        GenericMethod<Integer> gm2=new GenericMethod<Integer>();
        gm2.show(2);
        GenericMethod<Boolean> gm3=new GenericMethod<Boolean>();
        gm3.show(true);
    }
}

泛型方法:

public class GenericMethod01 {
    public <T> void show(T t){
        System.out.println(t);
    }
}
public class GenericDemo02 {
    public static void main(String[] args) {
//        GenericMethod<String> gm1=new GenericMethod<String>();
//        gm1.show("ak");
//        GenericMethod<Integer> gm2=new GenericMethod<Integer>();
//        gm2.show(2);
//        GenericMethod<Boolean> gm3=new GenericMethod<Boolean>();
//        gm3.show(true);
        
        GenericMethod01 gm01 =new GenericMethod01();
        gm01.show("qbb");
        gm01.show(121);
        gm01.show(true);
    }
}

4.4 泛型接口:

泛型接口:

package GenericDemo01;

public interface GenericInterface<T> {
    public void show(T t);
}

泛型实现类:

package GenericDemo01;

public class GenericImp <T> implements GenericInterface<T>{
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

4.5 泛型通配符

为了表示各种泛型List的父类,可以使用类型通配符
1、类型通配符:<?>
2、List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
3、这种带通配符的List仅表示各种泛型List的父类,并不能把元素添加到其中
如果说不希望List<?>是任何泛型List的父类,只希望它代表某一类泛型List的父类,可以使用类型通配符的上限和下限。
1、类型通配符上限:<?extends 类型>;
2、List<?extends Number>:它表示的类型是Number或者其子类型;
3、类型通配符下限:<?super 类型>;
4、List<?super Number>:它表示的类型是Number或者其父类型 。

import java.util.ArrayList;
import java.util.List;

public class GenericSign {
    public static void main(String[] args) {
        List<?> list1=new ArrayList<Object>();
        List<?> list2=new ArrayList<Number>();
        List<?> list3=new ArrayList<Integer>();
        List<?> list4=new ArrayList<String>();
        
//        List<?extends Number> list5=new ArrayList<Object>();//上限是Number所以创建对象的时候不能是Number的父类
        List<? extends Number> list6=new ArrayList<Integer>();
//        List<? super Number> list7=new ArrayList<Integer>();//下限是Number所以创建对象时,不能是Number的子类
        List<? super Number> list8=new ArrayList<Object>();
    }
}

4.6可变参数

可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
格式:修饰符返回值类型 方法名(数据类型… 变量名){}
范例:public static int sum(int… a){}

可变参数注意事项:
1、范例中的a其实是一个数组
2、如果一个方法多个参数,包含可变参数,可变参数要放在后面
(int b,int… a)

public class GenericPara {
    public static void main(String[] args) {
        System.out.println(sum(12,34,56,665));
    }
    public static int sum(int... a){
        int sum=0;
        for(int i:a){
            sum+=i;
        }
        return sum;
    }
}

4.7可变参数的使用

import java.util.Arrays;
import java.util.List;

public class GenericDemo03 {
    public static void main(String[] args) {
        List<String> list=Arrays.asList("h","e","l","l","o");
//        list.add("item");不支持,因为会修改list的长度,不可变列表
//        list.remove("h");不支持,因为会修改list的长度,不可变列表
        list.set(0,"I");//支持,set不会修改list的长度
        System.out.println(list);
    }
}

Arrays工具类中有一个静态方法:
1,public static List asList(T… a):返回由指定数组支持的固定大小的列表
2,返回的集合不能做增删操作,可以做修改操作(不可变列表)

List接口中有一个静态方法:
public static List of(E… elements):返回包含任意数量元素的不可变列表

Set接口中有一个静态方法:
1,public static Set of(E… elements):返回一个包含任意数量元素的不可变集合
2,在给元素的时候,不能给重复的元素
3,返回的集合不能做增删操作,没有修改的方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值