美文网首页
范型--Java与kotlin

范型--Java与kotlin

作者: 紫鹰 | 来源:发表于2021-04-29 17:00 被阅读0次

缘起(为解决什么问题而生)

  • 加强类型安全
  • 减少类型强转次数
  • 限定参数或返回值范围

类型安全

  • 类型赋值检查
  • 类型调用检查

协变与逆变

Java实现

先看一个常见的例子

    TextView tv = new Button(context);
    List<Button> buttons = new ArrayList<Button>(); 
    List<TextView> textViews = buttons;// 报错

Java的范型类型会在编译过程进行类型擦除,为了保证类型安全,不允许这样赋值。

但在实际应用中,我们经常需要这种赋值,Java中提供范型通配符? extends? super来解决这个问题

  • 上界通配符 ? extends

      List<Button> buttons = new ArrayList<Button>();
      List<? extends TextView> textViews = buttons;//合法
     
      TextView textView = textViews.get(0);// 合法
      textViews.add(textView)//报错
    

add报错的理解:
List<? extends TextView>类型未知,他可能是List<TextView>,也可能是List<Button>。对于List<Button>,调用add显然是不可以的,实际情况是,编译器无法确定究竟属于哪一种,因此无法执行下去,就报错了。

  • 下界通配符? super

      List<? super Button> buttons = new AyyayList<Button>()//合法
      List<? super Button> buttons = new AyyayList<TextView>()//合法
      List<? super Button> buttons = new AyyayList<Object>()//合法
      
      Object object = buttons.get(0)//get 出来的都是Object类型
      Button button = new Button(context);
      buttons.add(button)// 合法
    

表示未知类型,所以获取出来的数据可以用Object来接,虽然不知道List中存放的类型究竟是哪种类型,但是Button一定是这些类型中的子类型,因此可以调用add

PECS 法则:「Producer-Extends, Consumer-Super」。

使用范型通配符? extends 来使范型支持协变,但是只能读不能修改(不能使用add方法)
使用范型通配符? super来使范型支持逆变,但是只能写不能读(获取到的值都是Object类型)

kotlin实现

使用关键字 out 来支持协变,相当于Java中的 ? extends
使用关键字 in 来支持逆变,相当于Java中的? super

*

Java 单独使用,相当于 ? extends Object
kotlin中等效于 * ,相当于 out Any

多边界

Java中用 &amp 连接多个边界

 class Monster <T extends Animal &amp Food>{
 } 

kotlin 中使用 where 关键字

 class Monster <T> where T :Animal, T :Food

类型擦除

Kotlin java为泛型声明用法执行的类型安全检测仅在编译期进行。 运行时泛型类型的实例不保留关于其类型实参的任何信息。 其类型信息称为被擦除。例如,Foo<Bar>的实例会被擦除为 Foo<*>

  • 自动类型转换
    编译阶段编译器进行类型强转

  • 多态冲突
    例父类

      class Parent<T>{
         private T valte;
         
         public T getValue(){
            return value;
         }
         
         public void setValue(T value){
            this.value = value; 
          }
          
       }
    

子类

   class Child extends Parent<String> {
   
        @override
        public void setValue(String value){
             super.setValue(value);
        }
        
        @overide
        public String getValue(){
             return super.getValue();
        }
     }

子类生成的字节码反编译过来,有四个方法

setValue(String value)//重写的方法
setValue(Object value)//编译器生成的桥方法
String getValue()//重写的方法
Object getValue()//编译器生成的桥方法

编译器生成的桥方法的内部实现,就只是去调用我们自己重写的那两个方法

范型实例化

Java实现方式

new T()无法实现,部分原因是因为擦除,而另一部分原因是因为编译器不能验证T是否具有默认构造器。

直接传入T 对应的Class或者Type,类内部直接通过反射创建

  class. newInstance()

kotlin实现方式

在kotlin中,由于范型的强化以及阻止才出等特性的存在,使得范型实例化成为可能。
通过 inline 和 reifiied 可以保证泛型类型被实化

inline fun <reified T: Any> new(): T {
   val clz = T::class.java
   val mCreate = clz.getDeclaredConstructor()
   mCreate. isAccessible = true
   return mCreate. newInstance()
}

带参范型数实例化

inline fun <reified T: Any> new(vararg params: Any): T {
   val clz = T::class.java
   val paramTypes = params.map { it::class.java }.toTypedArray()
   val mCreate = clz.getDeclaredConstructor(*paramTypes)
   mCreate. isAccessible = true
   return mCreate. newInstance(* params)
}

相关文章

  • 范型--Java与kotlin

    缘起(为解决什么问题而生) 加强类型安全 减少类型强转次数 限定参数或返回值范围 类型安全 类型赋值检查 类型调用...

  • 泛型

    与Java泛型相同,Kotlin同样提供了泛型支持。对于简单的泛型类、泛型函数的定义,Kotlin 与 Java ...

  • CoreJava笔记 - 范型程序设计(2)

    范型代码和Java虚拟机 关键知识:类型擦除Java的范型是编译器层次的范型,而在Java虚拟机上并没有范型类。在...

  • CoreJava笔记 - 范型程序设计(5)

    反射与范型 由于类型擦除,反射无法得到关于范型类型参数的信息。 范型的Class类在Java的反射库中,Class...

  • Kotlin 泛型 VS Java 泛型

    建议先阅读我的上一篇文章 -- Java 泛型 和 Java 泛型一样,Kotlin 泛型也是 Kotlin 语言...

  • Kotlin泛型与DSL重点记录

    泛型 kotlin的泛型语法与java类似,比如声明一个泛型类: 类型参数约束 类似于java中的entends关...

  • 【Android】 Kotlin(七)泛型

    深入理解Kotlin泛型 Kotlin 的泛型与 Java 一样,都是一种语法糖,即只在源代码中有泛型定义,到了c...

  • 面试-Kotlin相关

    Kotlin Kotlin与Java的关系 Kotlin如何与Java混编 协程

  • Kotiln学习

    From Java To Kotlin 打印日志 Java Kotlin 常量与变量 Java Kotlin nu...

  • Kotlin系列之Kotlin与Java语法区别

    打印日志 Java Kotlin 常量与变量 Java Kotlin null声明 Java Kotlin 空判断...

网友评论

      本文标题:范型--Java与kotlin

      本文链接:https://www.haomeiwen.com/subject/lpuwrltx.html