十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
本篇内容主要讲解“Kotlin内联类与类型别名的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Kotlin内联类与类型别名的使用方法”吧!
创新互联专注为客户提供全方位的互联网综合服务,包含不限于网站设计制作、网站设计、承德县网络推广、微信平台小程序开发、承德县网络营销、承德县企业策划、承德县品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供承德县建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com
内联类的支持版本目前是1.3及以上。
内联类的使用其实很简单,只需要我们在class前面加上一个inline关键字即可,如下面这样:
inline class WoMan(private val name: String) {val length: Intget() =name.length fun greet() {println("Hello, $name") } }
跟普通的类看上去没什么区别,不过我们show bytecode之后看看代码是怎么样的
public static final int getLength_impl/* $FF was: getLength-impl*/(String $this) { return $this.length();}
public static final void greet_impl/* $FF was: greet-impl*/(String $this) { String var1 = "Hello, " + $this; boolean var2 = false; System.out.println(var1);}
String name = WoMan.constructor-impl("唐三");WoMan.greet-impl(name);
其实最后都变成了静态方法调用了,那如果我们不用inline关键字修饰的话会是怎么样呢
public final class WoMan { private final String name; public final int getLength() { return this.name.length(); } public final void greet() { String var1 = "Hello, " + this.name; boolean var2 = false; System.out.println(var1); } public WoMan(@NotNull String name) { Intrinsics.checkNotNullParameter(name, "name"); super(); this.name = name; } }
其实就是简单的Java类而已,调用的话我们还是得对象方法才可以。
WoMan name = new WoMan("唐三");name.greet();
然后我们再说一下内联函数的使用要求:内联类必须含有唯⼀的⼀个属性在主构造函数中初始化。在运⾏时,将使⽤这个唯⼀属性来表⽰内联类的实例。
其实就是起到了包装器的作用,我们发现使用的时候跟普通的类的使用方法一样,没有任何区别,但是我们在性能上就已经做得很好了,我们在实例化一个对象的时候,就会把对象存储到JVM堆上,我们在存储和使用对象实例时会有性能损失 - 堆分配和内存提取的性能代价很高。虽然看起来每个对象性能开销微不足道,但是累积起来,它对代码运行速度产生严重的影响。如果我们能够在不受性能影响的情况下获得强类型系统的所有好处,那不是很好吗?实际上,Kotlin新特性inline class
就是为了解决这样的问题而设计的。
这样我们即在性能方面做了节省,还不影响我们获得强类型的使用的所有的好处,这样何乐不为呢?
上面的例子当中我们声明的内联类对象的时候其实就相当于声明了我们内联类里面包装的变量而已,从而避免了对象的创建和销毁。
内联类的柱构造函数里面只能有一个参数并且是只能是可读的,但是呢,它的内部是可以拥有成员属性的,只要它们仅基于构造器中那个基础值计算,或者从可以静态解析的某个值或对象计算 - 来自单例,顶级对象,常量等。可以将参数设置为私有的,但是构造函数必须是共有的,我们的内联类可以继承接口,但是不能继承类,也不能被任何类继承,不能作为内部类实现,也不支持内联枚举类。
typealias类型别名的时候跟内联类有一些相似之处,也容易混淆。
因为它们都包含基础类型,所以内联类很容易与类型别名混淆。但是有一些关键的差异使它们在不同的场景下得以应用。
比如我们需要定义一个变量,可能是用户名称或者用户密码等,那么类型肯定是字符串嘛,作为函数形参的声明的时候我们一般都是name:String即可,可是我们想表达的更清楚一些呢,就可以用类型别名还使用我们自己定义的名字。
typealias userName = String
class WoMan(private val name: userName) {}
可以看到使用起来跟String没什么区别,只是表达的更清楚了。
内联函数一方面来说使用的时候我们需要进行拆箱的操作,而类型别名就不需要了,可是类型别名在同一类型的时候是无法区分,比如我们同事声明了两个类型别名username,password而且都是字符串,可是我们的定义函数方法里面需要的参数是可以改变顺序的,因为我们的参数类型虽然是不同的类型别名,但是都是一个String类型的,所以这一点内联函数是完全可以不用考虑的,因为内联函数就是一个基本类型的包装体,不同的包装体肯定不一样,所以我们的顺序是不能改变的。
typealias userName = Stringtypealias passWord = Stringfun test(name: userName, pwd: passWord) { }
上面就很容易看到了,当我们name和pwd的传参数顺序不一样的时候,编译器是无法做出检测的,运行期也不会报错的。
但是内联函数就是包装之后就是不同的类。
inline class Username(val name: String)inline class Password(val pwd: String)fun test2(name: Username, pwd: Password) { }
当我们调用函数的时候传递的参数顺序改变的话,编译器是会报错的。
所以使用起来各取所需吧,各有各的使用场景。
到此,相信大家对“Kotlin内联类与类型别名的使用方法”有了更深的了解,不妨来实际操作一番吧!这里是创新互联网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!