不断学习,做更好的自己!💪
视频号CSDN简书欢迎打开微信,关注我的视频号:程序员朵朵点我点我==、===和equal的区别? ==和equal
的作用相同,===比较内存地址
var和val的区别?
var
:可变引用,具有可读和可写权限,值可变,类型不可变val
:不可变引用,具有可读权限,值不可变,但是对象的属性可变
Kotlin 中默认参数的作用以及原理? 作用:配合 @JavaOverloads
可以解决Java
调用Kotlin
函数重载的问题。 原理:Kotlin
编译的默认参数是被编译到调用的函数中的,所以默认参数改变的时候,是需要重新编译这个函数的。
Kotlin 中顶层函数的原理 顶层函数实质就是 Java
中的静态函数,可以通过 Kotlin
中的 @Jvm:fileName
自动生成对应的 Java
调用类名。
中缀函数是什么?注意点? 中缀函数需要是用infix关键字修饰,如downTo
:
public infix fun Int.downTo(to: Int): IntProgression {
return IntProgression.fromClosedRange(this, to, -1)
}
注意点是函数的参数只能有一个,函数的参与者只能有两个。
解构函数的本质? 解构声明将对象中的所有属性,解构成一组属性变量,而且这些变量可以单独使用,可以单数使用的原因是通过获取对应的component()
方法对应着类中每个属性的值,这些属性的值被存储在局部变量中,所以解构声明的实质是局部变量。
扩展函数的本质? 扩展函数的本质就是对应Java
中的静态函数,这个静态函数参数为接受者类型的对象,然后利用这个对象去访问对象中的属性和成员方法,最后返回这个对象的本身。
扩展函数和成员函数的区别?
- 实质不同:扩展函数实质是静态函数,是外部函数,成员函数是内部函数。
- 权限不同:扩展函数访问不了私有的属性和成员方法,成员函数可以。
- 继承:扩展函数不可复写,成员函数可以复写。
Kotlin 中常用的类的修饰符有哪些?
open
:运行创建子类或者复写子类的方法。final
:不允许创建子类和复写子类的方法。abstract
:抽象类,必须复写子类的方法。
在Kotlin
中,默认的类和方法的修饰符都是final
的,如果想让类和方法能够被继承或者复写,需要显示的添加open
修饰符。
Kotlin中可见性修饰符有哪些?
public
:所有地方可见protected
:子类中可见private
:类中可见internal
:模块中可见,一个模块就是一组一起编译的Kotlin文件
Java
默认的访问权限是包访问权限,Kotlin
中默认的访问权限是 public
。
Kotlin中的内部类和Java中的内部类有什么不同?
Kotlin
:默认相当于Java中的静态内部类,如果想访问类中的成员方法和属性,需要添加inner关键字修饰。Java
:默认持有外部类引用,可以访问成员方法和属性,如果想声明为静态内部类,需要添加static关键字修饰。
Kotlin属性代理背后原理? 可以简单理解为属性的settter、getter访问器内部实现交给了代理对象来实现,相当于使用一个代理对象代替了原来简单属性的读写过程,而暴露外部属性操作还是不变 的,照样是属性赋值和读取,只是setter
、getter
内部具体实现变了。
object 和 companion object 的一些特点? 共同点: 定义单例的一种方式,提供静态成员和方法。
不同点:
- object:用来生成匿名内部类。
- companion object:提供工厂方法,访问私有的构造方法。
lambda 表达式有几种?
- 普通表达式:()->R。
- 带接收者对象的表达式:T.()->R,可以访问接收者对象的属性和成员方法。如apply。
kotlin 和 Java 内部类或者 lambda 表达式访问局部变量有什么不同?
Java
中的内部类:局部变量必须是final
声明的,无法去修改局部变量的值。Kotlin
中lambda
表达式:不要求final
声明,对于非final
修饰的lambda
表达式,可以修改局部变量的值。
如果想在Java中的内部类修改外层局部变量的值,有两种方法:用数组包装或者提供包装类,Kotlin中lambda能够访问并修改局部变量的本质就是提供了一层包装类:
class Ref(var value:T)
修改局部变量的值就是修改 value
中的值。
使用 lambda 表达式访问的局部变量有什么不同? 默认情况下,局部变量的生命周期会被限制在声明这个变量的函数中,但是如果它被lambda捕捉了,使用这个变量的代码可以被存储并稍后执行。
class Apple {
lateinit var num:(() -> Int)
fun initCount(){
val count = 2
num = fun():Int{
return count * count
}
}
fun res():Int{
return num()
}
}
fun main(args: Array) {
val a = Apple()
a.initCount()
val res = a.res()
println(res)
}
如上面代码所示,局部变量count
就被存储在lambda
表达式中,最后通过Apple#res
方法引用表达式。
原理:当你捕捉final
变量的时候,它的值会和lambda
代码一起存储。对于非final
变量,它的值会被封装在一层包装器中,包装器的引用会和lambda
代码一起被存储。
带来的问题:默认情况下,lambda表达式会生成匿名内部类,在非显示声明对象的情况下可以多次重用,但是如果捕获了局部变量,每次调用的时候都需要生成新的实例。
序列是什么?集合类和序列的操作符比较? Sequence
(序列)是一种惰性集合,可以更高效地对元素进行链式操作,不需要创建额外的集合保存过程中产生的中间结果,简单来讲,就是序列中所有的操作都是按顺序应用在每一个元素中。比如:
fun main(args: Array) {
val list = mutableListOf("1","2","3","4","5","6","7","8","9")
val l = list.asSequence()
.filter { it.toCharArray()[0]
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?