关于java泛型机制深层次的了解

11 篇文章 0 订阅
1 篇文章 0 订阅

 一、概述

泛型是Java 1.5引入的新特性。泛型的本质是参数化类型,这种参数类型可以用在类、变量、接口和方法的创建中,分别称为泛型类、泛型变量、泛型接口、泛型方法。将集合声明参数化以及使用JDK提供的泛型和泛型方法是相对简单的,而编写自己的泛型类型会比较困难,但是还是值得思考与学习如何去编写。泛型提供了编译时类型安全检测机制,该机制允许程序员在**编译时检测**到非法的类型。

java 中泛型标记符:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  • - 表示不确定的 java 类型

二、泛型的优势

  1. 提高代码的安全性和表述性
  2.  提高代码的重用率
  3. 泛型机制只在程序编译阶段起作用,只是给编译器参考的
  4. 使用泛型的好处:集合中存储的元素类型统一了。

从集合中取出的元素类型是泛型指定的类型,不需要进行大量的向下转型!

三、泛型机制的代码实现

注意:Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,这也就是通常所说类型擦除 。

所谓的泛型擦除:

  • Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除
import java.util.*;
public class test{
    public static void main(String args[]) {
        //用泛型来指定集合中存储的数据类型
         List<Anmial> generic = new ArrayList<>();
         //使用泛型之后List集合只能允许存储Anmial类型的数据了,
         //generic.add(123);
         cat c= new cat();
         Birld b = new Birld();
         generic.add(c);
         generic.add(b);
         //获取迭代器,这个表示迭代器迭代的是Anmial类型
         Iterator<Anmial> it = generic.iterator();
         while (it.hasNext()){
             //使用泛型之后,每一次迭代返回的数据都是Anmail类型
             Anmial a = it.next();
             a.run();       //动物在跑。
                            //猫在睡觉。
             //调用子类型特有的方法还是需要向下转型的!
             if (a instanceof cat){
                 cat x = (cat)a;
                 x.sleep();         //动物在跑。
             } else if (a instanceof Birld) {
                 Birld y = (Birld)a;       
                 y.fly();           //鸟儿在飞。
             }
         }
    }
}
class Anmial{
    public void run(){
        System.out.println("动物在跑。");
    }
}
class cat extends Anmial{
    public void sleep(){
        System.out.println("猫在睡觉。");
    }
}
class Birld extends Anmial{
    public void fly(){
        System.out.println("鸟儿在飞。");
    }
}

四、JDk8以后引入了:自动类型推断机制

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class test{
    public static void main(String args[]) {
        //JDk8以后引入了:自动类型推断机制。(又称为钻石表达式)
        //ArrayList<这里的类型会自动推断>(),前提是JDK8之后才允许
        List<Anmial> myList = new ArrayList<>();
        myList.add(new cat());
        List<String> l2 = new ArrayList<>();
        l2.add("http:www.baidu.com");
        l2.add("http:www.QQ.com");
        Iterator<String> it = l2.iterator();
        while (it.hasNext()){
            //直接通过迭代器获取了String类型的数据
            String s = it.next();
            //直接可以调用String类的substring方法截取字符串。
            //如果没有通过迭代器获取String类,则不能直接调用substring的方法
            System.out.println(s.substring(5));
        }
    }
}

五、自定义泛型

//自定义泛型时,<>中是一个标识符,随便写
public class test<T>{
    public void doSome(T o){
        System.out.println(o);
    }
    public static void main(String args[]) {
        test<String> s = new test<>();
        s.doSome("abc");//abc
        //类型不匹配
        //s.doSome(12345);


        Anmial<Integer> i = new Anmial<>();
        i.run(123);//123

        Anmial<String> a = new Anmial<>();
        //返回一个String类型的数据
        String ss = a.get();
        System.out.println(ss);//null
    }
}
class Anmial<E>{
    public void run(E w){
        System.out.println(w);
    }
    public E get(){
        return null;
    }
}

六、泛型机制在什么时候使用?

通常是在集合框架中使用,遇到< >就要定义泛型。

  • 其实<>就是用来接收类型的,在使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

七、<? extends T>和<? super T>的区别

分两种情况:

①作为容器时 

<? extends T>没有意义,只能存null

<? super T>可以放它本身和其子类类型,可以存null

②作为方法参数时

<? extends T>支持其本身类型及其子类类型,也就是设置上限。

<? super T>支持本身类型及其父类类型,也就是设置下限。

八、泛型的使用限制

1. 无法使用基本数据类型

2. 无法创建泛型参数类型的实例

public <E> void test(E e) {
    E e1 = new E(); // 编译时错误
}

但是可以通过反射来创建对象  :

public <E> void test(E e) {
    E e1 = e.getClass().newInstance();// 正确
}

3. 不能为static字段(属性)声明为泛型类型

4. 无法创建泛型类型的数组

5. 无法创建、捕获或者抛出泛型类型异常

6. 泛型擦除到原生类型的方法无法重载


支持:如果你觉得博主的文章的不错或者对你有帮助,可以点一个免费的关注支持一下博主,你的鼓励将是我创作的最大动力!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

-今非昔比°

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值