🔥  1、请简述什么是 Kotlin?它有哪些特性?🔥

kotlin和java一样也是一门jvm语言最后的编译结果都是.class文件,并且可以通过kotlin的.class文件反编译回去java代码,并且封装了许多语法糖,其中我在项目中常用的特性:扩展、 lamdba表达式、函数式编程、空安全等。

扩展 (使用非集成的方式 扩张一个类的方法和变量):比方说 px和dp之间的转换

 lamdba表达式:lamdba表达式并不是kotlin的专利,java中也有,但是有限制, 像 setOnClickListener

另外就是函数式编程 在java8中提供了streamApi 对集合进行map sort reduce等等操作,但是对android api有限制,为了兼容低版本,几乎不可能使用streamApi

判空语法 省略了许多if xxx==null 的写法 也避免了空指针异常 aaa?.toString ?: "空空如也" 当aaa为空的时候 它的值被"空空如也"替代
aaa?.let{
it.bbb
}
当aaa不为空时 执行括号内的方法

 省略了findViewById ,使用kotlin 就可以直接用xml中定义的id 作为变量获取到这个控件,有了这个 butterknife就可以淘汰了,使用databinding也能做到,但是,非常遗憾,databinding的支持非常不好,每次修改视图,都不能及时生成,经常要rebulid才能生成.

 默认参数 减少方法重载

 外说明,kotlin会是apk大小在混淆后增加几百k 。

🔥 2、Kotlin 中的扩展函数是什么? 🔥

kotlin中的扩展函数,实际上就是通过给类添加 public static final 函数的做法来实现,这样做可以减少utils类的使用。

扩展函数是静态解析的,是采用静态分派的过程来处理。这意味着调用的扩展函数是由函数调用所在的表达式的类型来决定的,而不是由表达式运行时求值结果决定的。这意思其实就是在使用该扩展函数的时候,如果类本身和其子类都进行了同一个函数的扩展,这函数是不会有重写关系的,在使用的时候,只会根据需要使用该方法的对象的实际类型来决定是调用了哪个,就是相当于调用静态方法。而不是动态分派。

🔥3、 如何在 Kotlin 中用值初始化一个数组?🔥 

 在 Java 中,可以初始化数组,例如: int numbers[] = new int[] {10, 20, 30, 40, 50}

Kotlin 的数组初始化是什么样子的? val numbers: IntArray = intArrayOf(10, 20, 30, 40, 50) 

🔥4、Kotlin 中 fold 和 reduce 的基本区别是什么 ?🔥

fold接受一个初始值,传递给它的 lambda 的第一次调用将接收该初始值和集合的第一个元素作为参数。 listOf(1, 2, 3).fold(0) { sum, element -> sum + element } 对 lambda 的第一次调用将使用参数0和1。 如果您必须为您的操作提供某种默认值或参数,那么能够传入初始值是很有用的。

reduce不采用初始值,而是从集合的第一个元素作为累加器开始(sum在以下示例中调用) listOf(1, 2, 3).reduce { sum, element -> sum + element } 此处对 lambda 的第一次调用将使用参数1和2。

 🔥 5、 Kotlin 中的 var 和 val 有什么区别?🔥

Kotlin 中 val 和 var 的区别
val 和 var 属性之间最显着的区别是前者是不可变的。我们可以改变 var 变量的值,但我们不能改变 val 变量的值。
它们类似于 Java 中的 final 关键字。val 和 var 变量之间的其他一些区别是:
现在我们知道了 val 和 var 之间的区别,让我们看一些我们尝试更改它们的值的示例。

在 Kotlin 中使用 var 关键字 在这个例子中,我们将使用 var 关键字来声明一个变量并尝试改变它的值。 var v = "Hello!" fun main() { println("This is a var variable: "+v); // Changing the value of var variable v = "Welcome!"; println("New value of the var variable is: " +v); } 输出: var 变量示例: 在 Kotlin 中使用 val 关键字 在这里,我们将使用 val 关键字创建一个不可变变量并尝试更改其值。 val v = "Hello!" fun main() { println("This is a val variable: "+v); // Changing the value of val variable v = "Welcome!"; println("New value of the val variable is: " +v); }

val 变量示例: 正如我们在输出中看到的,更改 val 变量会引发错误:Val cannot be reassigned。 在 Kotlin 中更改 val 变量的属性 虽然我们不能更改使用 val 关键字声明的变量的值,但我们仍然可以更改它们的属性。让我们看一个使用 val 声明变量并更改其属性的示例。 fun main(args: Array) { val student = Student("David Shaw",1) print(student) student.name = "Joe Smith" print("\n"+student) } data class Student(var name: String = "", var id: Int = 0)

🔥 6、阐述Kotlin 在哪里使用 var 和 where val? 🔥 

在值经常变化的地方使用var。例如,在获取 android 设备的位置时: var integerVariable : Int? = null 在整个班级的价值没有变化的情况下使用val 。例如,您想以编程方式设置 textview 或按钮的文本。 val stringVariables : String = "Button's Constant or final Text"

 🔥 7、 简述Kotlin 中的数据类 ? 🔥

Kotlin 数据类,在 Kotlin 中,您可以创建一个data类来保存数据。您希望将类标记为data的原因是让编译器知道您正在创建此类来保存数据,然后编译器会自动为您的数据类创建多个函数,这将有助于管理数据。在本指南中,我们将学习数据类和编译器自动生成的函数

我们经常创建主要目的是保存数据的类。在 Kotlin 中,这称为数据类并标记为data:
data class User(val name: String, val age: Int)
为了确保生成代码的一致性和有意义的行为,数据类必须满足以下要求:
主构造函数至少需要一个参数;
所有主要的构造函数参数都需要标记为 val 或 var;
数据类不能是抽象的、开放的、密封的或内部的

 🔥  8、 如何在 Kotlin 中创建单例?🔥

只需使用object. object SomeSingleton 上面的 Kotlin 对象将被编译为以下等效的 Java 代码: public final class SomeSingleton { public static final SomeSingleton INSTANCE; private SomeSingleton() { INSTANCE = (SomeSingleton)this; System.out.println("init complete"); } static { new SomeSingleton(); } }

这是在 JVM 上实现单例的首选方法,因为它可以实现线程安全的延迟初始化,而不必依赖像复杂的双重检查锁定这样的锁定算法。

🔥 9、 以下代码执行的结果是什么? 🔥 

val aVar by lazy { println("I am computing this value") "Hola" } fun main(args: Array) { println(aVar) println(aVar) }

第lazy一次访问 Lazy 属性时,会进行初始化(lazy()函数调用)。第二次,这个值被记住并返回:

I am computing this value
Hola
Hola

🔥  10、 解释 Kotlin 中的 Null 安全性 ?🔥 

Kotlin 的类型系统旨在消除代码中空引用的危险。

空引用异常。在 Java 中,这相当于 aNullPointerException或简称 NPE。

可空引用)和不能保存的引用(non-null引用)。例如,String 类型的常规变量不能保存 null:

var a: String = "abc" a = null // compilation error 为了允许空值,我们可以将变量声明为可空字符串,写成String?: var b: String? = "abc" b = null // ok print(b)