忙碌了一年,期间也学习了不少东西,但是没时间整理,乘着快过年了不是很忙的时候把学习的 Kotlin 知识记录一下。使用的好处就不用说了。
-
数据类型
和 Java 一样,Kotlin 的数据类型也基本一个意思,只不过在 Kotlin 里是真的万物皆对象。
Boolean类型 Boolean
Number整型 Short Int Long
Number浮点型 Float Double
Number字节 Byte
字符型 Char
字符串型 String
Arrays 数组型 intArrary StringArrary 等
在申明变量时的使用方式上和 Java 也是有一点的区别。
val aBoolean : Boolean = true
val age: Int= 26
val name: String= "Leon"
val args: IntArrary= "intArraryOf(1,2,3,4,5)"
Kotlin中是不允许隐式转换
, 每个 Number 类型的变量支持如下方法进行转换:
toByte() : Byte
toShort() : Short
toLong() : Long
toFloat() : Float
toDouble() : Double
toChar() : Char
如:val a : Int = b.toInt()
-
常量与变量
val : 申明为常量,类似于Java中的 final 只能赋值一次,后续不可更改
var : 申明变量,就是不加 final 的变量,允许重新赋值
val age: Int= 26 赋值为26后 后续行为中不允许再更改
var aBoolean : Boolean = true 后续行为中允许把值更改为 false
val a = 1 如果没有申明类型,Kotlin 会自动 类型推导 为"Int"类型
运行时常量:val x = getX()
编译器常量:const val x = getX()
-
字符串操作
字符串模板$
,如果需要打印字符串加别的类型的日志时可以通过以下方式:
val year : Int = 2021
System.out.println("今年是 $year 年")
打印出: 今年是2021年
字符串比较 ==
和 ===
a == b 表示比较内容, 即类似 Java 的 a.equals(b)
a === b 表示比较对象是否相同
-
类和对象
创建一个类和对象
// 方式一:如果只有一个构造方法时 constructor 可以省略
class Star constructor(var name : String, var age : Int, var sex : Int) {
// 初始化代码块
init{
println("new了一个明星 名字$year 年龄$age 性别$sex")
}
}
// 创建一个22岁名字叫Leon的男明星对象
val star: Star= Star( "Leon",22,1)
类的继承
首先把 Star 类加了一个 Open 前缀
open class Star (var name : String, var age : Int, var sex : Int)
// 继承 Star 类
class ChildStar(var name : String, var age : Int, var sex : Int) : Star (name ,age,sex) {
init{
println("new了一个童星 名字$year 年龄$age 性别$sex")
}
}
// 创建一个8岁名字叫Alisa的女童星对象
val star: Star= Star( "Alisa",8, 2)
class <类名> { <成员> }
提取多个类的共性得到一个更抽象的类,即父类。子类拥有父类的一切特征。子类也可以自定义自己的特征。所有类都最终继承自 * Any *
-
空类型和智能类型转换
空类型
在java中我们通常在Util类中处理部分逻辑最后得到结果,一般情况下得到的是两种结果, 1. 返回的所需数据 2.返回的 null。如下:
// Java
public static String getName(){
if(...) {
return "Leon";
}
return null;
}
String name = Util.getName()
if(name != null){
println(name.length())
}
但是这种写法在Kotlin中却不行, 因为Kotlin会认为你这的方法返回的值并不安全,可能会导致空异常。所以在Kolint中的写法是:
open fun getName() :String? {
if(...) {
return "Leon";
}
return null;
}
val name : String? = Util.getName()
println(name?.length())
在函数中如果返回值为null会强制在返回类型中加上?
.使用时也同样需要在变量名后面加上?
, 代表是可空类型。
在平时使用中, 我们会申明不少变量, 为遇到如下几种情况:
val value1 : String = "你好"
var value2 : String? = null
一种是确定变量的值, 一种是不确定, 需要默认是null的。如果是第二种, 则声明时类型后面必须要加上?
,否则编译器爆红, 并且不可使用 val
修饰。
如果返回类型是可空的, 但是又不想使用?
时 可以使用!!
来告诉编译器,你可以确定这个值不会为空。(这种方式需要慎重)
var value : String = null // 申明了一个可空的变量
override fun onCreate(savedInstanceState:Bundle?){
value = "你好" // 在使用时就可以肯定是有赋值的
Log.e(TAG, value?.length) // 但是在使用时还是必须加上`?`, 怎么办呢?
Log.e(TAG, value!!.length) // 可以使用双`!!`告诉编译器 '我可以确定他不会为空'
}
任意类型都有可空和不可控两种
val notNull: String = null // 错误,不能为空
val nullable: String? = null // 正确, 可以为空
val notNull.length // 正确,不为空的值可以直接使用
val nullable.length // 错误,可能为空,不能直接获取长度
val nullable!!.length //正确,强制 认定nullable不可空
val nullable?.length //正确,强制 若nullable为空,就返回空
智能类型转换
public staticc void main(String... args){
Star childstar = new Star();
// 方式1
(Star)chilstar.getName()
//方式2
if(childstar instanceof Star){
println((Star)chilstar.getName())
}
}
以上代码中足以体现出Java中不智能的表现, 明明ChildStar就是继承与Star, 但是在使用时还需要强转一次,方式2中也明明做了 instanceof 判断,在使用时还是需要强转一次。下面使用Kotlin来体现:
fun main(args :Array<String>){
val childstar = Star()
if(childstar is Star){
println(childstar.getName())
}
}
在Kotlin中我们通过了 is
关键字判断了是否是 Star 类型, 如果是编译器就自动推到出了 childstar 是 Star 的子类,已经不需要再次强转了。
Java Style 类型转换
val sub: SubClass = parent as SubClass // 类型与Java的类型转换,失败则抛出异常
Kotlin安全类型转换
val sub: SubClass = parent as? SubClass // 如果转换失败,返回null,不抛异常
Kotlin智能类型转换
if(parent is SubClass) parent.<子类的成员> // 编译器尽可能的推导类型,远离无用的类型转换
-
区间 ( Range )
区间是一个数学上的概念,表示范围,CloseRange的子类。比如[0, 1024]
的这个整型区间的表达为
val range1 :IntRange = 0..1024
除了这种方式外还有一个关键字 until
也可以表达区间:
val range2 : IntRange = 0 until 1024
但是这种方式是和第一种是有区别的,我们通过for循环来看一下:
for(i in range1 ){
println(i) // 最后输出的是1024
}
for(j in range2){
println(j) // 最后输出的是1023
}
由此可见 0 until 1024 是一个 半开区间 [0, 2014)
-
数组 (Array)
除了 Array 外 Kotlin 还给我们提供了 IntArry, ShortArray, ByteArray, CharArry
等。
val arrayOfInt : IntArray = intArrayOf(1,3,5,4,5)
val arrayOfChar : CharArray = charArrayOf('h','e','l','l','o')
val arrayOfString = Array<String> = arrayOf("你","好")
val arrayOfStar = Array<Star> = arrayOf(childStar1,childStar2)
// 数组的遍历
for (i in arrayOfInt) {
parintlin(i)
}
// 打印童星中的第二个
parintlin(childStar2[1].getName())
// 改变数组的第一个元素
arrayOfInt [0] = 10
// 切片
parintlin(arrayOfInt.sliec(1..2)) // 打印[3,5]
网友评论