您现在的位置是:群英 > 开发技术 > 编程语言
Java泛型机制怎样解释,是怎样的?
Admin发表于 2022-01-20 19:46:59832 次浏览

    这篇我们来聊一聊Java泛型机制,对于Java泛型机制的问题,有一些朋友在面试的时候会遇到,面试官会问题说一下java的泛型机制是怎样的,那么我们究竟该如何来回答呢?下面我们一起来探讨一下。

    精简版回答

    Java在开发时,通过使用菱形语法< >,使一个类、接口或者方法具有接受泛指的一群类作为参数,泛指的类最终由尖括号里的规则所限定,泛指类通常用大写字母表示,一般用字母T,后期经过Java编译器编译,泛型将被擦除,根据具体使用的类,替换泛型,生成class字节码,所以泛型是对Jvm透明的。

    豪华版回答

    泛型于JDK1.5正式引入

    Java引入泛型背景

    Java集合是允许放入多种类型的,例如

    List list=new ArrayList();
    list.add("String");
    list.add(1024);

    这在JDK1.5之前是常见的使用方式,即便放在今天的JDK下,也是允许的,那么类似于这种集合的使用方式,就会带来一些问题,就是集合中究竟放了哪些类型,恐怕只有创建集合的人才知道,其他调用者,根本无法确定,这样在大型项目里,极易出现问题,调用者强转集合里的某个对象,一旦类型错误,就会报错,这种错在当时编译阶段是无法发现的,只有运行时才被发现,为了解决类似问题,JDK引入了泛型。

    泛型类型

    引入泛型后,从而可以在编译阶段,检查类型是否符合要求,很大程度上,杜绝了盲目的类型转换。 泛型主要工作在编译器,编译后,JVM运行时,是无法感知泛型的。 泛型分为普通泛型和通配泛型。

    1.普通泛型

    这类泛型顾名思义,就是支持调用时传入任意类型,但是调用时,等号左右俩边泛型必须一致。JDK1.7右侧菱形可以省略。

class Test<T>{...} //声明时
Test<Integer> test = new Test<Integer>(); //调用时
Test<Integer> test = new Test(); //1.7调用时

    3.界限泛型

<?>//无界泛型,任意类型都匹配
<T extends ClassA>//有界泛型 - 继承自某父类
<T extends InterfaceB>//有界泛型 - 实现某接口
<T extends ClassA & InterfaceB & InterfaceC ... >//有界泛型 - 多重边界
<T super ClassC>//有界泛型 - 指定类父类

    泛型擦除

    刚才说到,泛型只在写代码时和编译时起作用,而Jvm加载class运行时是无感透明的,是因为编译器编译时将泛型擦除了,简单不严谨的说就是:把类或方法上的那个<>尖括号干掉了,根据尖括号里的规则换成具体的类,所以Jvm运行时根本不知道这段代码里之前有过泛型,这样做是为了兼容,前面说到泛型是JDK1.5才引入的,这样,即便引入泛型,现有的Jvm也不需要大改,只需要改一下编译器即可,对于这种编译器能感知的语法,而虚拟机无法感知的,人们把这种语法称作语法糖(suger),编译器经过 脱糖(Desuger) 后,拿到干货,交给虚拟机去执行。

    泛型擦除机制

//Pair的泛型
public class Pair<T> {

    private T mFirst;
    private T mSecond;

    public T getmFirst() {
        return mFirst;
    }

    public void setmFirst(T mFirst) {
        this.mFirst = mFirst;
    }

    public T getmSecond() {
        return mSecond;
    }

    public void setmSecond(T mSecond) {
        this.mSecond = mSecond;
    }
}

//Pair的原始类型
//无论何时定义一个泛型类型,都会自动提供一个相应的 原始类型
public class Pair {

    private Object mFirst;
    private Object mSecond;

    public Object getFirst() {
        return mFirst;
    }

    public void setFirst(Object mFirst) {
        this.mFirst = mFirst;
    }

    public Object getSecond() {
        return mSecond;
    }

    public void setmSecond(Object mSecond) {
        this.mSecond = mSecond;
    }
}

//如果调用Pair<T extends String>编译擦除后得到如下=
class Pair{
    private String mFirst;
    private String mSecond;
    ...
}

    当泛型作为方法的入参时,擦除后换成通配泛型的下界,例如add方法

public static void insertElements(List<? super A> list){
    //Add进来的都是层级“小于等于”A的,也就是下界
    list.add(new A());
    list.add(new B());
    list.add(new C());
}

    当泛型作为方法的回参时,擦除后换成通配泛型的上界,例如get方法

public void processElements(List<? extends A> elements){
   //for循环挨个get list 里的数据,都当做A,也就是都当做上界
   for(A a : elements){
      System.out.println(a.getValue());
   }
}

对于泛型的类型擦除说再多,看再多博客,不如官方定义准确,放一段Oracle官方对于类型擦除的文档

Type Erasure
Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic 
programming. To implement generics, the Java compiler applies type erasure to:
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. 
The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods.Insert type casts if 
necessary to preserve type safety.Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no 
runtime overhead.

    关于Java泛型机制的内容就介绍到这,现在大家应该能说出Java泛型机制究竟是怎么回事了吧。最后,希望大家阅读完这篇文章能有所收获,想要了解更多大家可以关注其它的相关文章。

文本转载自PHP中文网

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

标签: java泛型机制
相关信息推荐
2022-05-10 16:01:28 
摘要:本篇文章给大家带来了关于Python的相关知识,其中主要总结了24个非常实用的Python开发技巧,包括了all or any、bashplotlib、collections等等,希望对大家有帮助。
2022-07-23 17:42:42 
摘要:本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。
2022-11-11 17:47:03 
摘要:C语言标识符有关键字、用户标识符、预定义标识符三类。C语言规定,标识符只能由字母、数字和下划线组成,并且第一个字符必须是字母或下划线,不能是数字。
云活动
推荐内容
热门关键词
热门信息
群英网络助力开启安全的云计算之旅
立即注册,领取新人大礼包
  • 联系我们
  • 24小时售后:4006784567
  • 24小时TEL :0668-2555666
  • 售前咨询TEL:400-678-4567

  • 官方微信

    官方微信
Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
微信公众号
返回顶部
返回顶部 返回顶部