您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Kotlin空安全,反射,注解
1Kotlin空安全,反射,注解 导读1.Kotlin如何保证null安全的处理理?2.如何在运⾏行行时通过反射来检查代码?3.kotlin的注解对编译器器有什什么影响?2空安全空指针是任何⼀一个java开发⼈人员的噩梦,不不管他⼯工作多久。这是由于他未能正确处理理空指针。在其他语⾔言中,都⽤用不不同的思想避免这种问题。创造这个空指针的⼈人说:这是在1965年年发明的,我也挡不不住诱惑,因为它太容易易实现了了。在C语⾔言中⼀一个简单的空指针引⽤用就能导致崩溃,在Java⾥里里⾯面变⾼高级了了,出现了了⼀一个NullPointerException,jvm不不会崩溃。但可能是由于⼀一个trycatch,在写代码的时候,记得捕获住哦(在这个上⾯面吃了了很多亏……)。groovy和C#引⼊入设计允许编译器器捕捉潜在nullable代码。//待定突然想到⼀一个问题。为什什么应⽤用在某些界⾯面崩溃后,还能看⻅见其他界⾯面?但是有些崩溃,整个应⽤用就彻底崩溃了了?我在想是不不是某些异常虽然出现了了,但是jvm不不会崩溃,所以程序crash后,后⾯面的界⾯面还能展示出来。对于某些崩溃,直接把jvm搞崩溃了了,那么整个app也就崩溃了了。这⾥里里有个前提就是,你启动了了好多的界⾯面,昀上层的崩溃了了,才能看⻅见这样的问题。这是推测。nullsafe不不是⼀一个空容器器,不不强迫程序员抛出异常,会交给类型系统和编译器器。Kotlin类型系统致⼒力力于消灭空引⽤用。唯⼀一可能引起NPE异常的可能是:明确调⽤用throwNullPointerException()外部java代码引起⼀一些前后⽭矛盾的初始化(在构造函数中没初始化的成员在其它地⽅方使⽤用)3Nullabletypes在Kotlin类型系统中可以为空和不不可为空的引⽤用是不不同的。⽐比如,普通的String类型的变量量不不能为空:vara:String=abca=null//编译错误允许为空,我们必须把它声明为可空的变量量:varb:String?=abcb=null现在你可以调⽤用a的⽅方法,⽽而不不⽤用担⼼心NPE异常了了:vall=a.length()但如果你想使⽤用b调⽤用同样的⽅方法就有可能报错了了:vall=b.length()//错误:b不不可为空SmartcastfungetName():String?=WQ//Smartcast//fungetName():String?{returnhello}//Smartcast也可以这样valname=getName()//name.length//直接写报错,编译器器检测到可能为nullif(name!=null){//Smartcastprintln(name.length)}4Safenullaccess智能转换是⼀一个⾮非常好的特性,提供了了⼀一个可读的⽅方式分⽀支处理理null。然⽽而,当我们有链式操作,每⼀一步都可能产⽣生⼀一个零,很快就会变得不不可读的代码。就像这样: 层级太深了了。使⽤用kotlin的smartcast可以实现的更更优雅: 5使⽤用这个操作符(?)时,编译器器会⾃自动插⼊入null检查以确保我们不不访问null.通过查看字节码: 这⾥里里的关键指令2、9、16、23,这显示编译器器执⾏行行⼀一个null检查,如果是null跳指令32岁之前添加⼀一个堆栈返回null。6Forceoperator我们有时候不不想要编译器器的检测⾮非空功能,可以直接使⽤用操作符(!!).valnullableName:String?=georgevalname:String=nullableName!! 7Elvisoperator例例如java中,如果有任何⼀一个空就是默认值,否则是原始值,我们需要这么写: Kotlin为我们提供了了Elvisoperator(?:)作为替换。据说,你把头侧向操作符的时候看起来像是猫王的发型,但也许会有⼀一个不不同名称。(此处应有猫王图⽚片)8 真⼈人图⽚片9 10这其实像java中的三⽬目运算符。valnullableName:String?=...valname:String=nullableName?:default_name和safenullaccess⼀一起访问valnullableAddress:Address?=nullvalpostcode:String=nullableAddress?.postcode?:default_postcodeSafecasting我们知道是字符串串,但是编译器器不不知道啊,可以显示指定。vallocation:Any=LondonvalsafeString:String?=locationas?StringvalsafeInt:Int?=locationas?IntOptionals上⾯面讨论了了kotlin的nullsafe的⼀一些⽅方法。但这不不是唯⼀一的。他们使⽤用⼀一个类型,表示⼀一个函数或表达式可能会或可能不不会返回⼀一个值.在java8以上的javaOptional.CreatingandreturninganOptional我们可以⽤用⼀一个值在⼀一个可选的简单调⽤用静态⽅方法:valoptionalName:OptionalString=Optional.of(william)11如果我们希望为空值创建⼀一个可选的,那么我们可以使⽤用静态⽅方法空:valempty:OptionalString=Optional.empty()通常情况下直接使⽤用Nullable,它是⼀一个空的实例例存在,不不可变没有状态。如果有⼀一个返回null,我们会返回字符串串?如果有值,直接原来的类型。可选类型有什什么意义?Java8引⼊入Optional类来防⽌止空指针异常,Optional类昀先是由Google的Guava项⽬目引⼊入的。Optional类实际上是个容器器:它可以保存类型T的值,或者保存null。使⽤用Optional类我们就不不⽤用显式进⾏行行空指针检查了了。通过⼯工⼚厂⽅方法创建Optional类。注:创建对象时传⼊入的参数不不能为null。如果传⼊入参数为null,则抛出NullPointerException。//调⽤用⼯工⼚厂⽅方法创建Optional实例例OptionalStringname=Optional.of(Sanaulla);//传⼊入参数为null,抛出NullPointerException.OptionalStringsomeNull=Optional.of(null);ofNullable与of⽅方法相似,唯⼀一的区别是可以接受参数为null的情况//下⾯面创建了了⼀一个不不包含任何值的Optional实例例//例例如,值为'null'Optionalempty=Optional.ofNullable(null)isPresent⽤用来判断Optinal是否有值。如果值存在返回true,否则返回false。OptionalemptyOptional=Optional.empty();//emptyOptional为空,打印结果为trueSystem.out.println(emptyOptional.isPresent());OptionalStringofOptional=Optional.of(wang);//ofOptional有值,打印结果为true12System.out.println(ofOptional.isPresent());UsinganOptionalget⽅方法将获取Optional中value的值,如果存在值,则返回该值,否则抛出NoSuchElementException。OptionalStringgetOptional=Optional.of(ThisisaOptional);StringvalueOptional=getOptional.get();//打印结果:ThisisaOptionalSystem.out.println(valueOptional);如果Optional实例例有值则将其返回,否则返回orElse⽅方法传⼊入的参数。//如果值不不为null,orElse⽅方法返回Optional实例例的值。//如果为null,返回传⼊入的消息。//输出:Thereisnovaluepresent!System.out.println(empty.orElse(Thereisnovaluepresent!));//输出:SanaullaSystem.out.println(name.orElse(Thereissomevalue!));参考:flection反射反射是在运⾏行行时,⽽而不不是在编译时。它可以创建类的实例例,查找函数,以及调⽤用它们,检查注解,寻找字段,发现参数和泛型,以及了了解在编译时⽆无法知道的细节。为什什么使⽤用反射?假如我们有两个程序员,⼀一个程序员在写程序的时候,需要使⽤用第⼆二个程序员所写的类,但第⼆二个程序员并没完成他所写的类。那么第⼀一个程序员的代码能否通过编译呢?这是不不能通过编译的。利利⽤用Java反射的机制,就可以让第⼀一个程序员在没有得到第⼆二个程序员所写的类的时候,来完成⾃自身代码的编译。Java反射的作⽤用Java:描述反射机制的作⽤用?举⼏几个反射的应⽤用?⼀一个例例⼦子让你了了解Java反射机制本章介绍反射类和函数,在Kotlin中如何使⽤用反射。Kotlin的反射需要引⼊入第三⽅方包kotlin-reflect,不不在kotlin-stdliblibrary的标准库中,按需选择。Kotlin的反射使⽤用KClass,每⼀一个类型都有⼀一个KClass的实例例在运⾏行行时包含的细节功能,属性,注解,其他信息等等。得到KClass的实例例⽤用::classvalkclass1:KClassString=harry::classvalkclass2:KClassString=victoria::classvalkclass3:KClassString=String::class我们可以像java⼀一样使⽤用类名完全限定:valkclass=Class.forName(com.packt.MyClass).kotlinkclass⽀支持⾼高级特性。14Instantiationusingreflection在运⾏行行时创建时编译不不知道的实例例。classPositiveInteger(value:Int=0)funcreateInteger(kclass:KClassPositiveInteger):PositiveInteger{returnkclass.createInstance()}⽤用createInteger创建了了⼀一个PositiveInteger实例例。createInteger的缺点是它只为类⼯工作,没有参数或者可选参数,可选的参数有默认值。我们来想象这样⼀一个例例⼦子:把cvs⽽而是的数据导⼊入到我们的⼀一个java程序A中。A程序会接受不不同类型的数据的导⼊入,我们希望在运⾏行行时添加新的ingesters,⽽而不不⽤用修改核⼼心代码。数据源:ingesters.propsingesters=com.packt.ingester.AmazonIngester,com.packt.ingester.GoogleIngester加载这个属性⽂文件,分解字符串串,提取名字,然后反射,实例例化他们。如果有ingesters的参考,可以调⽤用他们。这需要他们的⼊入⼝口函数实现常⻅见的接⼝口:interfaceIngester{funingest():Unit}funmain(args:ArrayString){valprops=Properties()pr
本文标题:Kotlin空安全,反射,注解
链接地址:https://www.777doc.com/doc-1249837 .html