-
kotlin方法类型_Kotlin类型检查,Kotlin类型铸造
2020-07-12 19:24:52kotlin方法类型Today we will look into Kotlin type checking and smart type casting.... 今天,我们将研究Kotlin类型检查和智能类型转换。 我们将使用Kotlin在线游乐场编写代码段。 Kotlin类型检查 (K...kotlin方法类型
Today we will look into Kotlin type checking and smart type casting. We will use Kotlin Online playground for code snippets.
今天,我们将研究Kotlin类型检查和智能类型转换。 我们将使用Kotlin在线游乐场编写代码段。
Kotlin类型检查 (Kotlin Type Checking)
Type Checking is the way to check the type of a data at runtime. In Java, we have the
instanceof
keyword to check the type. Kotlin usesis
and!is
keywords to check whether a property is and is not of a certain type respectively.类型检查是在运行时检查数据类型的方法。 在Java中,我们有
instanceof
关键字来检查类型。 Kotlin使用is
和!is
关键字检查属性是否是分别是某种类型的不是 。Let’s look at an example code for the same.
让我们看一个相同的示例代码。
var myProperty = "xyz" var otherProperty = 1 if(myProperty is String) { println("type is String") } else{ println("unknown type") } if(otherProperty !is Double) { println("not a string") } else{ println("unknown type") }
The first if-else expression would print type is String. The second would give a compilation error since Kotlin is powerful enough to determine the types at compile time itself.
第一个if-else表达式将打印类型为String。 第二个将给出编译错误,因为Kotlin足够强大,可以在编译时自行确定类型。
Let’s create a list of
Any
objects and check the type of each element.让我们创建一个
Any
对象的列表,并检查每个元素的类型。We’ll use the
when
statement to check the type of each element in a for loop.我们将使用
when
语句来检查for循环中每个元素的类型。val anyList: List<Any> = listOf("JournalDev.com", "Java", 101, 12.5f,12.5456789,false) for(value in anyList) { when (value) { is String -> println("String: '$value'. Capitalize :${value.capitalize()}") is Int -> println("Integer: '$value'") is Double -> println("Double: '$value'") is Float -> println("Float: '$value'") else -> println("Unknown Type") } }
Following is the output of the above code.
以下是上述代码的输出。
Kotlin智能型铸造 (Kotlin Smart Type Casting)
Smart type casting is one of the most interesting features available in Kotlin. It automatically casts a property to the desired type on the right hand side if the condition meets.
智能类型转换是Kotlin中最有趣的功能之一。 如果条件满足,它将在右侧自动将属性强制转换为所需的类型。
fun getName(obj: Any?) { if (obj == null || obj !is String) { return } val string = obj println("Length of the string is ${string.length}") } getName(null) getName("Anupam")
In the above code, we don’t need to unwrap the optional. If the smart cast passes the above null checker, optional is unwrapped automatically.
在上面的代码中,我们不需要打开可选的包装。 如果智能强制转换通过了上述空检查器,则将自动解开Optional选项。
The output printed from the above piece of code is given below.
下面给出了以上代码输出的输出。
The same equivalent code in Java would look like this:
Java中相同的等效代码如下所示:
class MyJava { public static void main (String[] args) throws java.lang.Exception { // your code goes here MyJava mj = new MyJava(); mj.printStringLength("Anu"); } public void printStringLength(Object obj) { if (obj instanceof String) { String str = (String) obj; System.out.print("String substring is "); System.out.print(str.substring(1)); } } }
In the above code, we’re first checking the
instanceOf
and then explicitly type casting. Kotlin makes it way simpler thanks to Smart Casting.在上面的代码中,我们首先检查
instanceOf
,然后显式键入强制类型转换。 借助Smart Casting,Kotlin使其变得更加简单。二元运算符的智能转换 (Smart Casting With Binary Operators)
Smart Casting is also possible with binary operators as shown in the below code.
如以下代码所示,使用二进制运算符也可以进行智能转换。
fun newStringOnlyIfLength6(str: Any): Boolean { return str is String && str.length == 6 } print(newStringOnlyIfLength6("Kotlin")) //prints true fun stringOnlyIfLength6(str: Any): Boolean { return str !is String || str.length == 6 } print(stringOnlyIfLength6("Kotlin")) //prints true
In the above code, in the first function, if the first condition is true, Kotlin type casts the parameter in the second parameter to the same type.
在上面的代码中,在第一个函数中,如果第一个条件为true,则Kotlin类型会将第二个参数中的参数强制转换为相同类型。
班上的聪明演员 (Smart Casts in Classes)
Let’s create classes that implement an interface as shown below:
让我们创建实现接口的类,如下所示:
import java.util.* fun main(args: Array<String>) { class Car : Vehicle { override fun printDetails() { println("AUDI Rocks") } } class Bike : Vehicle { override fun printDetails() { println("Bullet fires") } } val printMe: Vehicle val random = Random() fun rand(from: Int, to: Int): Int { return random.nextInt(to - from) + from } printMe = if (rand(0, 10) % 2 == 0) { Car() } else { Bike() } if (printMe is Car) { printMe.printDetails() } if (printMe is Bike) { printMe.printDetails() } } interface Vehicle { fun printDetails() }
The Random function gets a random integer between 0 to 10. Based on whether it’s even or odd, the interface creates instantiates from either of the classes.
Random函数获取一个介于0到10之间的随机整数。基于它是偶数还是奇数,接口从任何一个类创建实例化。
The
is
operator then calls the method in the if expressions by smart casting the type of the class.然后,
is
运算符通过智能转换类的类型在if表达式中调用该方法。Note: The Kotlin compiler does not smart cast when it cannot guarantee that the value hasn’t changed between check and usage. It always smart casts for
val
properties and can never do so forvar
properties.注意:当Kotlin编译器不能保证在检查和使用之间该值未发生变化时,它不会智能强制转换。 它始终对
val
属性进行智能转换,而永远不会对var
属性进行转换。显式铸造 (Explicit Type Casting)
We can explicitly type cast properties in Kotlin using the
as
operator.我们可以使用
as
运算符在Kotlin中显式键入类型属性。val object: Any = "Hello World" val str: String = object as String println(str.length)
The as operator is unsafe. It can lead to
ClassCastException
similar to Java in scenarios shown below.as运算符不安全。 在下面显示的方案中,它可能导致类似于Java的
ClassCastException
。var y = null var x = y as String println(x) // crashes
x is not a nullable type, so it cannot be set to null. For this case, we’ll can do either of the following:
x不是可为null的类型,因此不能将其设置为null。 对于这种情况,我们可以执行以下任一操作:
var y = null var x = y as String? println(x)
This allows us to set x as a null.
这使我们可以将x设置为null。
But the above approach would fail when:
但是上述方法在以下情况下将失败:
var y = 5 var x = y as String? println(x) //crashes
So we need to use the
as?
operator which instead of giving a runtime exception, sets a null value if the cast doesn’t succeed.那么我们需要使用
as?
如果强制转换不成功,该运算符将设置为null值,而不是给出运行时异常。var y = 5 var x = y as? String println(x) //gives a null
That’s all for type checking and smart casting in kotlin programming language.
这就是用Kotlin编程语言进行类型检查和智能转换的全部内容。
翻译自: https://www.journaldev.com/19684/kotlin-type-checking-kotlin-type-casting
kotlin方法类型
-
Kotlin 类型检测与类型转换
2019-07-04 19:23:05类型检测 is 运算符 is运算符可以检查对象A是否是特定的类型,还可以检查一...Kotlin中我们可以在运行时通过 is 或者 !is 来检查对象是否符合所需的类型 println("abc" is String) println("abc" !is String) ...类型检测
- is 运算符
is运算符可以检查对象A是否是特定的类型,还可以检查一个对象是否属于某种数据类型(Int、String等)。
is运算符相当于java中的 instanceof
Kotlin中我们可以在运行时通过 is 或者 !is 来检查对象是否符合所需的类型
println("abc" is String) println("abc" !is String) println(null is Any) println(null is Any?)
输出结果如下
true false false true
类型自动转换
在java中,当我们用 “string” instanceof String 为true的时候,如果我们想使用string变量,还需要显示的强制类型转换。
Object o = "abc"; if (o instanceof String){ int length = ((String) o).length(); }
Kotlin中大多数情况是不需要显示的强制类型转换,编译器会自动通过is检查,并在需要是自动转换。
val a = "abc" println(a.length)
as运算符
as运算符用于执行引用类型的显示类型转换,如果类型与指定类型相符,就会转换成功,如果类型不兼容,使用as?就会返回null
@JvmStatic fun main(args: Array<String>) { val ani = Ani() val dog = Dog() ani as Dog } open class Ani { } class Dog : Ani() { }
如果是 父类ani 转换成 子类 dog类会报错如下
说明Kotlin中父类是禁止转换成子类的。按照Liskov替换原则,父类转换为子类是对OOP的严重违反。学习《Kotlin入门到进阶实战》
- is 运算符
-
kotlin空类型转换和智能类型转换
2020-08-30 21:50:27空类型转换 fun getName(): String?{ return null } fun main(args: Array<String>) { val name = getName() //为什么报错,因为kotlin不支持空类型 println(name.length) //?就是我知道他是空类型,...空类型转换
fun getName(): String?{ return null } fun main(args: Array<String>) { val name = getName() //为什么报错,因为kotlin不支持空类型 println(name.length) //?就是我知道他是空类型,然后我让他执行这个空类型,这就是类型安全转换 println(name?.length) }
空类型安全转换也可以这样写,这样的写法哪怕你写的是空对象编译器也会继续编译成功,不会直接编译失败这是另外一种安全转换的写法,当出现需要这种方式获取长度时候就可以获取其字符串的长度
fun main(args: Array<String>) { /* val name: String = getName()?: return //为什么我又不报错了? 因为?表达的意思就是我前面的表达式如果为空就继续执行,不会报错 println(name.length)*/ val value: String ?= "dsdsadasda" //这种情况也无法获取其长度,该怎么办呢? /* println(value.length)*/ //这样的写法就是告诉编译器我知道这样写不行,但是你只管执行,然后它就能直接获取到这个字符串的长度了 println(value!!.length) }
智能类型转换
fun main() { //这就是智能转换 //Chlid2为父类,Parent2继承它的父类, //这是向下转型,父类对象的类型是子类 //这是实例化父类的对象,我现在是拿不到子类中方法的,如何去拿到呢? val chlid2 : Chlid2 = Parent2() //通过这个判断,它的意思就是说我的chlid2是Parent2实例 /*if (chlid2 is Parent2)*/ //这样就拿到子类中的方法了 println(chlid2.name()) }
首先我的父类实例化对象是拿不到子类中的方法的,呢要如何拿到呢?
通过智能转换就可以去实现子类方法
这是我子类中定义的方法:
我通过智能转换,就可以实现父类实例化对象拿到子类的方法fun main() { //这就是智能转换 //Chlid2为父类,Parent2继承它的父类, //这是向下转型,父类对象的类型是子类 //这是实例化父类的对象,我现在是拿不到子类中方法的,如何去拿到呢? val chlid2 : Chlid2 = Parent2() //通过这个判断,它的意思就是说我的chlid2是Parent2实例 if (chlid2 is Parent2) //其放在java中就需要强转,这样 is 就是说它是不为空的类型就不需要强转了 //这样就拿到子类中的方法了 println(chlid2.name()) } 最终返回的结果就是子类中的呢个方法 ## 还有比如 **//:: Kotlin 中 双冒号操作符 表示把一个方法当做一个参数,传递到另一个方法中进行使用,通俗的来讲就是引用一个方法。 //使用 !! 时,会对对象进行非空判断,并且会像 java 代码一样抛出异常。 //?对象A ?: 对象B 表达式,意思为,当对象 A值为 null 时,那么它就会返回后面的对象 B。** val top :String? = "hello" println(top.length) //我直接获取长度是获取不到的,因为编译器不能信任这句话我们可以通过下面这个判断 //我告诉编译器它是这个可以信任的类型,就可以编译成功 if (top is String){ println(top.length) } ## 这就是另外一种智能类型转换 ## 智能类型转换——安全转换操作方式 /* * 智能转换安全,转换时不会抛出异常,如果没有加as?它会抛出类型转换异常,但是如果加了as?它会直接抛出null并不会抛出异常 * */ val ch:Chlid2 = Chlid2() val par:Parent2? = ch as? Parent2 /**/ println(par) 这段代码返回的结果为null
-
Kotlin智能转换
2020-12-27 17:32:42不同的是,在Kotlin中,编译器已经帮我们执行了类型转换,我们不用手动添加类型转换,我们把这种行为称为智能转换。 接下来,我们用一个简单的例子来加深对智能转换的理解。我们来编写一个函数对像**(1+2)+4这样...在Java中,我们需要用到instanceof关键字来判断一个对象是否是某种类型,在使用instanceof关键字判断之后,我们还需要显式地加上类型转换。而在Kotlin中,我们使用is检查来判断一个对象是否是某种类型。不同的是,在Kotlin中,编译器已经帮我们执行了类型转换,我们不用手动添加类型转换,我们把这种行为称为智能转换。
接下来,我们用一个简单的例子来加深对智能转换的理解。我们来编写一个函数对像**(1+2)+4这样简单的算术表达式求值。你会采用怎样的形式编码这种表达式?我们可以把它们存储在一个树状结构中,结构中每个节点要么是一次求和(Sum)要么是一个数字(Num)。Num永远都是叶子节点**,而Sum节点有两个子节点:它们是求和运算的两个参数。代码如下:
//注意:Expr接口没有声明任何方法,它只是一个标记接口, //用来给不同种类的表达式提供一个公共的类型。 interface Expr //声明类的时候,使用一个冒号(:)+接口名称,来标记这个类实现了这个接口。 class Num(val value:Int):Expr class Sum(val left:Expr,val right:Expr):Expr fun eval(e:Expr):Int{ if (e is Num){ //使用as关键字来表示到特定类型的显示转换 val num = e as Num //显示地转换成类型Num是多余的 return num.value } if (e is Sum){ //变量e被智能地转换了类型 return eval(e.left) + eval(e.right) } return 0 }
在上面代码中,Expr接口有两种实现,一个是Num类,表示表达式是一个数字,直接返回它的值。一个Sum类,表示一次求和,得先计算左右两个表达式的值,再返回它们的和。
最后总结一下:智能转换只在变量经过is检查且之后不再发生变化的情况下有效。当你对一个类的属性进行智能转换时,这个属性必须是一个val属性,而且不能有自定义的访问器。否则,每次对属性的访问是否都能返回同样的值将无从验证。借鉴资料:《Kotlin实战》
有兴趣的读者可以关注我的微信公众号,萌新一个,希望大家多多支持。我会在接下来的每个星期(至少3篇)不定期的把自己学习内容笔记同步到微信公众号。
-
Kotlin智能类型转换
2018-07-28 22:05:35package fenglei.demo....//Smart Cast智能转换 open class Parent() class Child : Parent() { fun getName(): String { return "hello" } } fun main(args: Array<String>) { pri... -
Kotlin as 类型转换运算符
2019-07-09 11:01:24起源:封装 DialogFragment 时自定义的 ViewHolder fun <T : View> getView(@IdRes viewId: Int): T { var view = mViews?.get(viewId) if (view == null) { view = mConvertView?.findViewById(viewId)... -
kotlin的智能类型转换
2020-12-10 22:26:35kotlin里面的智能类型转换有如下两个场景: 场景一:自动推断类型并转换 首先看下示例: var zhangsan: Zhangsan = Person("zhangsan") if (zhangsan is Person) { println(zhangsan as Person).name } 用... -
Kotlin 空类型安全与智能类型转换
2021-01-12 21:10:20在 Kotlin 中的类与接口 中我们已经讲了 Kotlin 的 类、接口 和 扩展方法,今天我们来讲 Kotlin 中的 空类型安全 和 智能类型转换。 二、Kotlin 空类型安全 2.1、空类型安全概念 Java 语言中是没有空类型安全这一... -
android Kotlin int类型和Long类型转换
2020-03-06 19:12:33在Kotlin开发中,即使Long类型较大,int类型的数值也不会自动转换为long类型。这与Java处理数字转换的方式不同。例如; 在Java中 int number1 = 102; long number2 = number1; //有效代码 这里,number1类型的 int ... -
Kotlin数据类型(三:基础数据类型转换)
2018-03-29 15:18:27在Java中从小到大,可以隐式转换,数据类型将自动提升。下面以int为例 这么写是ok的 int a = 2312; long b = a; 那么在Kotlin中 //隐式转换,编译器会报错 val anInt: Int = 5 val ccLong: Long = anInt //... -
kotlin中类型检查和类型转换
2018-12-20 10:54:00is操作符,可以在运行时检查一个对象与一个给定的类型是否一致,或者使用与它相反的!is操作符 fun main(arg: Array<String>) { var a :Any= 1 if (a is String) { print("是String") } if (a is ...
-
mmdetection源码注释
-
Java星选一卡通
-
搜索框单独组件
-
微服务系列第七十一季-Spring入门
-
【数据分析-随到随学】数据分析建模和预测
-
备战2021年软考信息系统项目管理师考试学习套餐
-
图像分类2
-
9张图告诉您 数据库的王者出现 HTAP
-
1232. 缀点成线
-
arXiv Journal 2021-01-17 with focus on Stefano Carrazza
-
基础的深度学习实验研究结果汇总笔记
-
JavaScript 显示和隐藏图片
-
STM32正交编码测速
-
【数据分析-随到随学】机器学习模型及应用
-
单元测试UnitTest+Pytest【Selenium3】
-
【Java基础】Comparable和Comparator两种比较器的区别(原理+实现)
-
【数据分析-随到随学】Python语法强化与数据处理
-
const和readonly
-
备战2021软考网络规划设计师历年真题套餐
-
21年新接口自动化测试视频postman教程 零基础接口测试