初学Java之泛型


目录

前言

一、简单理解泛型?

二、引出泛型

1.看一个需求分析)

2.泛型入门

3.泛型在集合中的好处

三、自定义泛型

1. 自定义泛型类

(1)语法

(2)泛型属性

(3)泛型方法

(2)使用规则

二、泛型接口

1. 基本语法

2. 细节

        3、泛型继承

四、通配符

(1) 支持任意泛型类型

五、结束语


前言

认识JavaSE中泛型的基本规则,作用,和使用环境

一、简单理解泛型?

        【泛型】 我们可以理解为广泛的类型,可以理解为 <> 为我们函数中的(),里面是参数列表,不过<> 中必须是引用类型。创建对象,调用方法时,指定类型。

二、引出泛型

1.看一个需求

代码如下(示例):规定在一个集合中,添加自定义Person类类型的数据,对Person类进行封装,并要求用getXXX返回其值,用传统方法实现代码如下:

(1)Person类的定义及main函数

class Person {//Person 类
    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 Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(new Person("张一凡",20));
        arrayList.add(new Person("刘一鸣",18));
        for (int i = 0; i < arrayList.size(); i++) {
            Person person = (Person)arrayList.get(i);//.get 返回Object,向下转型
            System.out.println(person.getAge()+"***" +
                    person.getName());
        }
    }

分析)

1. 我们可以看到对每一次的遍历,都要 向下转型 必定耗费资源,较低效率。

2. 同样如果我们不小心向集合中加入了不是 Person类的数据,编译不会出错,运行会出java.lang.ClassCastException,程序的健壮性较差。

2.泛型入门

    对上面一个问题 我们可以使用泛型,对集合中的数据类型进行限制,如果数据添加不符合,编译出错,容易检查,且不用向下转型就可使用getXX。

对上个问题改进-----使用泛型》代码如下:

public static void main(String[] args) {
        ArrayList<Person> arrayList = new ArrayList<>();//这两种方式都可以,推荐第一种
//,更简洁
        //ArrayList<Person> arrayList = new ArrayList<Person>();
            arrayList.add(new Person("张一凡",20));
            arrayList.add(new Person("刘一鸣",18));

        for (int i = 0; i < arrayList.size(); i++) {
            System.out.println(arrayList.get(i).getName()+
                    arrayList.get(i).getAge());
        }
    }

3.泛型在集合中的好处

1. 增强代码健壮性

2. 对某种特定的需求,可以提高效率。

3. 对集合中数据的类型进行限制。

三、自定义泛型

1. 自定义泛型类

(1)语法

class 类名 <E> {//<>中的字母 自定义
    
}

(2)泛型属性

  (1)可以在类成员(非静态成员)进行修饰,在创建这个对象时,类型就是确定

public class Generic02 {
    public static void main(String[] args) {
        new Animal<String,Double>("老虎",6.0).show();//Double 是 double 的封装类
    }
}
class Animal<E,F> {// 申明了两个泛型,完成对象的创建会确定其类型
   private E name;
   private F age;
   public void show () {
       System.out.println( "参数name的类型是" +
               name.getClass().getSimpleName()+
               "\t" + "参数age的类型是" +
               age.getClass().getSimpleName() );
   }

参数name的类型是String    参数age的类型是Double

(2)不能在静态属性使用泛型。原因:在创建对象之前,虚拟机 会在方法区先完成类加载,加载的同时,不能解析该属性的类型,故编译出错。

 cannot be referenced from a static context

(3)泛型方法

(1)语法

访问修饰符 <E,F> 返回类型 函数名称 (E e,F f ) {//<>中 字母可自定义

}

注意:如果没有<> 就不是泛型方法,而是方法使用了泛型。

        访问修饰符  返回类型 函数名称 (E e,F f ) {//<>中 字母可自定义

}

(2)如果静态方法使用泛型,则必须声明为泛型方法,否则会编译出错

 public static <E> void show(E e) {

    }

cannot be referenced from a static contex


(2)使用规则

   1 .调用该函数,传入参数时,会自动辨别类型

  public static void main(String[] args) {
        show("你好",15);
    }
    public static <E,F> void show (E e,F f ) {
        System.out.println(e.getClass()+" "+f.getClass());
    }
class java.lang.String class java.lang.Integer

2. 泛型在方法中的好处

(1) 可以接受任何参数,对这些参数进行类型辨析,然后对其处理。

二、泛型接口

1. 基本语法

interface A <e,t,,,> {//<>z中的字母和数量自定义

}

2. 细节

 1. (成员变量 只能是常量。默认修饰符 public static final)静态成员不能使用泛型。

 2. 在实现接口或者继承接口时,类型确定。 

3 . 如果没有指定,默认Object。

interface textone <K,V > {
    void show (K k,V v);
}
interface A extends textone <String,Integer>
    //接口继承声明了泛型的类型
{
    
}
class fast implements A {//类实现A接口,抽象方法中的类型就会匹配
    //接口A申明的类型
    @Override
    public void show(String s, Integer integer) {
        
    }
}

3、泛型继承

1. 泛型不具备继承

        即左右<>不能不同,列如 List<Object> list = new ArrayList<String>();//编译出错。

四、通配符

(1)<?> 支持任意泛型类型

    public static void main(String[] args) throws Exception {
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        ArrayList<String> stringArrayList = new ArrayList<>();
        printList(integerArrayList);
        printList(stringArrayList);
    }
    public static void printList (Collection<Object> list) {
        for (Object obj: list) {
            System.out.println(obj);
        }
    }

因为泛型不具有继承性 所以会编译出错 

改进:要用<?> 无边界通配符)

public static void main(String[] args) throws Exception {
        ArrayList<Integer> integerArrayList = new ArrayList<>();
        ArrayList<String> stringArrayList = new ArrayList<>();
        printList(integerArrayList);
        printList(stringArrayList);
    }
    public static void printList (Collection<?> list) {
        for (Object obj: list) {
            System.out.println(obj);
        }
    }
我们要注意 在 printList 方法中,不是使用 关于参数的函数,例如 list.add();,可以使用无光参数的比如 :list.size()。

3.< ? extends A > 支持 A 即 A的子类,规定泛型的上限。

List < ? extends 类型1> list = new ArrayList<类型2>();

     注解   类型2只能是类型1或者类型1的子类

 public static void main(String[] args) throws Exception { 
        List< ? extends Number> list = new ArrayList<Integer>();
        List< ? extends Number> list2 = new ArrayList<String>();
        //list2 错误,因为String 不是 Number 的子类
    }

4. < ? super A  > 支持 A 即 A 的父类,规定了泛型的下限

List < ? super 类型1> list = new ArrayList<类型2>();

     注解   类型2只能是类型1或者类型1的父类,不局限于直接父类

List<? super Floa> x = new ArrayList<Number>();//这是正确的
List<? super Integer> x = new ArrayList<Double>();//这是错误的

(5)总结

 对对象的权限

1.只读--------> extends 关键字 规定上限

2.只写---------> super 关键字,规定下限

五、结束语

对泛型及通配符的基础和我的浅微理解就总结到这了,欢迎大家观看,批评。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值