基本类型
在 Kotlin 中,所有东西都是对象,在这个意义上讲我们可以在任何变量上调用成员函数和属
性。 一些类型可以有特殊的内部表示——例如,数字、字符和布尔值可以在运行时表示为原
生类型值,但是对于用户来说,它们看起来就像普通的类。 在本节中,我们会描述 Kotlin 中
使用的基本类型:数字、字符、布尔值、数组与字符串。
数字
kotlin在处理数字时与java类似,但又不完全相同.
例如在数字没有隐式拓展;
有些情况下的字面值有所不同;
在kotlin中字符不是数字;
Double 64
Float 32
Long 64
Int 32
Short 16
Byte 8
十进制: 123
Long类型:123L
十六进制:0x01
二进制:0b11011000
不支持八进制
Double:123.5
Float:123.5f
可以使用下划线增加数组的可读性
val oneMillion=1_000_000
在 Java 平台数字是物理存储为 JVM 的原生类型,除非我们需要一个可空的引用(如
Int? )或泛型。 后者情况下会把数字装箱。
fun box(v:View){
val a:Int =10000
Log.d("meee",""+(a === a));
val b:Int?=a;
val c:Int?=a;
Log.d("meee",""+(b === c));//注意,装箱后不保证同一性,这里为false
//但会保持数字的相等
Log.d("meee",""+(b == c));//true
//假设代码,实际上不能被编译
//Long 和Int即使值相等也不能陪判断为==
val ten:Int? =10;
val tenL:Long?=ten;
Log.d("meee",""+(a==b));//false
//所以同一性还有相等性都会在所有地方悄无声息地失去
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
显式转换
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
val byte:Byte=1
/* //不能通过编译
val int:Int=byte*/
//显式转换
val int:Int=byte.toInt()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
运算
Kotlin支持数字运算的标准集,运算被定义为相应的类成员(但编译器会将函数调用优化为相
应的指令)
位运算
对于位运算,没有特殊字符来表示,而只可用中缀方式调用命名函数
shl(bits) – 有符号左移 (Java 的 << )
shr(bits) – 有符号右移 (Java 的 >> )
ushr(bits) – 无符号右移 (Java 的 >>> )
and(bits) – 位与
or(bits) – 位或
xor(bits) – 位异或
inv() – 位非
浮点数比较
相等性检测: a == b 与 a != b
比较操作符: a < b 、 a > b 、 a <= b 、 a >= b
区间实例以及区间检测: a..b 、 x in a..b 、 x !in a..b
fun calculate(v:View){
val num=0b1101_1000
Log.d("meee",""+num);//216
val num2=num shl 1
Log.d("meee",""+num2);//432
Log.d("meee",""+(0.9 in 1..10));
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
字符
字符用 Char 类型表示。它们不能直接当作数字
fun myChar(v:View){
val char:Char='a'
Log.d("meee","char:"+char);//a
/* //编译错误,类型不同不能判断
Log.d("meee",""+(char == 97));*/
//可以对char进行显式转换
Log.d("meee",""+(char.toInt() == 97));//true
}
布尔
布尔用 Boolean 类型表示,它有两个值: true 和 false 。
若需要可空引用布尔会被装箱。
内置的布尔运算有:
|| – 短路逻辑或
&& – 短路逻辑与
! - 逻辑非
数组
数组在 Kotlin 中使用 Array 类来表示,它定义了 get 和 set 函数(按照运算符重载约定
这会转变为 [] )和 size 属性,以及一些其他有用的成员函数:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
fun myArray(v:View){
//创建方式一
val numArray= arrayOf(1,2,3)
Log.d("meee",""+numArray[0]);//1,[]代表数组的get set
Log.d("meee",""+numArray[1]);//2
Log.d("meee",""+numArray[2]);//3
//创建一个大小为3空数组
var nullArray= arrayOfNulls<String>(3)
//创建方式二
val asc=Array(5,{i -> (i*i).toString()})//i为0 1 2 3 4
Log.d("meee",""+asc[0]);
Log.d("meee",""+asc[1]);
Log.d("meee",""+asc[2]);
Log.d("meee",""+asc[3]);
Log.d("meee",""+asc[4]);
/*与 Java 不同的是,Kotlin 中数组是不型变的(invariant)。这意味着 Kotlin 不让我们把
*Array<String> 赋值给 Array<Any> ,以防止可能的运行时失败*/
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
Kotlin 也有无装箱开销的专门的类来表示原生类型数组: ByteArray 、
ShortArray 、 IntArray 等等。这些类和 Array 并没有继承关系,但是它们有同样的方法属
性集。它们也都有相应的工厂方法:
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串
字符串用 String 类型表示。字符串是不可变的。 字符串的元素——字符可以使用索引运算
符访问: s[i] 。 可以用 for 循环迭代字符串:
fun string(v:View){
val str:String="a你b好c啊d"
for(char in str){
Log.d("meee",""+char);
}
}
字符串字面量
//转义字符
val helloworld="hello \n world"
Log.d("meee",""+helloworld);
//原生字符串,不识别任何转义字符
val rawString="""
|\b \n for in
|"\"/"
"""
Log.d("meee",""+rawString);
//可以通过trimMargin()来去除前导空格
//默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">") 。
Log.d("meee",""+rawString.trimMargin());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
字符串模版
val pwd="admin"
Log.d("meee","电脑的解锁密码是$pwd");//电脑的解锁密码是admin
Log.d("meee","电脑的解锁密码是${pwd.toString()}");//电脑的解锁密码是admin
如果你需要在原生字符串中表示字面值 $ 字符
(它不支持反斜杠转义),你可以用下列语法:
val rawStr2="""
|电脑的解锁密码是${'$'}
"""
Log.d("meee",""+rawStr2.trimMargin());//电脑的解锁密码是$
包
与 Java 不同,Kotlin 没有单独的“import static”语法; 所有这些声明都用 import 关键字导
入。
//引包
package foo.bar
//如果出现名字冲突,可以使用 as 关键字在本地重命名冲突项来消歧义:
import foo.Bar // Bar 可访问
import bar.Bar as bBar // bBar 代表“bar.Bar”
默认导入
有多个包会默认导入到每个 Kotlin 文件中:
kotlin.*
kotlin.annotation.*
kotlin.collections.*
kotlin.comparisons.* (自 1.1 起)
kotlin.io.*
kotlin.ranges.*
kotlin.sequences.*
kotlin.text.*
根据目标平台还会导入额外的包:
JVM:
java.lang.*
kotlin.jvm.*
JS:
kotlin.js.*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
If语句
fun testIf(v:View){
val a=1;
val b=2
if(a<b){
Log.d("meee","a<b");
}
if (b<a){
}else{
Log.d("meee","b>a");
}
//在kotlin中 if 是一个表达式,即它会返回一个值
//如果为代码块,则最后为该块的值
//if 作为表达该表达式需要有 else 分支。
var min=if (a<b) {
Log.d("meee","= =")
a
} else {11.1}
Log.d("meee","min:"+min);//1
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
When
类似switch,
也可以作为表达,同样必须要有else分支
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // 注意这个块
print("x is neither 1 nor 2")
}
}
//如果很多分支需要用相同的方式处理,则可以把多个分支条件放在一起,用逗号分隔:
fun testWhen2(v:View){
var x:Int=3
val str=when(x){
1,3,5 -> "单数"
2,4,6 -> "双数"
else -> "超出计算能力"
}
Log.d("meee",""+str);
}
//可以使用任意表达式作为分支条件
fun testWhen2(v:View){
var x:Int=3
val str=when(x){
1,3,5 -> "单数"
2,4,6 -> "双数"
//方法
getTen() -> "哟呵你还能输入个10进来"
//区间
in 666..999 -> "666"
//也可以通过类型判断,并且会自动转化,当然这里是编译不通过的
is String -> "string"
else -> "超出计算能力"
}
Log.d("meee",""+str);
}
fun getTen():Int=10;
//when 也可以用来取代 if - else if 链。 如果不提供参数,所有的分支条件都是简单的布
尔表达式,而当一个分支的条件为真时则执行该分支:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
For
for 循环可以对任何提供迭代器(iterator)的对象进行遍历,这相当于像 C# 这样的语言中
的 foreach 循环。语法如下:
for (item in collection) print(item)
循环体可以是一个代码块。
for (item: Int in ints) {
// ……
}
如上所述, for 可以循环遍历任何提供了迭代器的对象。即:
有一个成员函数或者扩展函数 iterator() ,它的返回类型
有一个成员函数或者扩展函数 next() ,并且
有一个成员函数或者扩展函数 hasNext() 返回 Boolean 。
这三个函数都需要标记为 operator 。
//如果你想获取数组或者集合的索引
//注意这种“在区间上遍历”会编译成优化的实现而不会创建额外对象。
//list
val list= ArrayList<String>()
list.add("你")
list.add("好")
list.add("啊")
for (index in 0 until list.size){
Log.d("meee",""+list.get(index));
}
for ((index,value) in list.withIndex()){
Log.d("meee","index is $index,value is $value");
}
//数组
val arr= arrayOf("1","2","3")
for (i in arr.indices){
Log.d("meee",""+arr[i]);
}
for ((index,value)in arr.withIndex()){
Log.d("meee","index is $index,value is $value");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
While doWhile
同java
返回和跳转
Kotlin 有三种结构化跳转表达式:
return 。默认从最直接包围它的函数或者匿名函数返回。
break 。终止最直接包围它的循环。
continue 。继续下一次最直接包围它的循环。
所有这些表达式都可以用作更大表达式的一部分:
val s = person.name ?: return//返回类型为Nothing
标签的使用
fun testLabel(v:View){
//labelName@创建标签
loop@ for (x in 1..100){
if (x%10==0){
//continue@loop跳过这次循环
continue@loop
}
if (x==51){
//终止这次循环
break@loop
}
Log.d("meee","x:"+x);
}
}
funct@{
//结束方法
return@lit
}
//隐式标签,该标签与接受该lambda 的函数同名。
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
类与继承
//类的声明由类名 类头(类型参数,主构造器) 类体组成
class TestClass1(val height:Double){
}
//类头和类体在不需要时可以省略
class TestClass2
构造器
//构造函数:一个主构造函数和多个次构造函数
class TestClass3 constructor(name:String){
}
//如果主构造器没有任何注解或者可见性修饰符,可以省略constructor这个关键字
class Test4 (name:String){
}
//主构造函数不能包含任何的代码,初始化的代码可以放到以init关键字修饰的代码块中
class TestClass5(var name:String){
//函数有顺序,现在的property是my name is $传入的参数,但如果放在init之后,则变成了sb
val property="my name is $name"
init{
name="sb";
}
}
//如果构造函数有注解或可见性修饰符,这个 constructor 关键字是必需的,并且这些修饰符在它前面:
/* class Customer public @inject constructor(name: String) {
}*/
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
//次构造器
class Person2 {
constructor (name:String) {
}
constructor () {
}
}
class Person() {
//次级构造器必须包含主构造器,或者通过别的次级构造器间接委托
constructor(name: String) : this() {
}
constructor(id:Int,name:String):this(name){
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
/*初始化块中的代码实际上会成为主构造函数的一部分。委托给主构造函数会作为次
构造函数的第一条语句,因此所有初始化块中的代码都会在次构造函数体之前执行。即使该
类没有主构造函数,这种委托仍会隐式发生,并且仍会执行初始化块:*/
class Constructors {
init {
println("Init block")
}
constructor(i: Int) {
println("Constructor")
}
}
把java文件转换成kotlin
code>>convert java file to kt file
javaBean类
//data关键字表明是javabean类
data class User(
var age :Integer,
var name:String)
/*会为 User类提供以下功能:
所有属性的 getters (对于 var 定义的还有 setters)
equals()
hashCode()
toString()
copy()
所有属性的 component1() 、 component2() ……等等(参见数据类)*/
摆脱fvbi
在module的gradle中应用
apply plugin: 'kotlin-android-extensions'
//可以直接通过控件的id访问该控件,顺便....不用写分号,真滴难受
button.text="你好啊"
方法
//普通方法
fun add(a: Int, b: Int): Int {
return a + b
}
//将表达式作为方法的返回值时,会自动判断返回类型
fun add2(a: Int, b: Int) = a + b
局部常量
定义
val a:Int =1
//自动推断
val b=1
//没有初始化则不能自动推断,且只能被赋值一次,未赋值使用编译报错
val c:Long
局部变量
var x:Int =1;
全局变量和常量
全局常量和变量与局部变量相同,但是必须在定义时初始化或抽象修饰
Lamdba的使用
button.setOnClickListener(object:View.OnClickListener{
override fun onClick(v: View?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
button.setOnClickListener{view->
}
button.setOnClickListener{
}
字符串模版
var a:String="小黄"
val saying="你是$a"//saying:你是小黄
//{}内是代码
val saying2="你是${a.replace("小黄","老江")}"//saying2:你是老江
使用可空值
//返回类型可以为null
fun getNull():Int?{
return null
}
public fun test(view:View){
var n=getNull()
//使用可空值时,必须进行非空判断
if (n!=null){
var x=n+1
Log.d("meee","x:"+x);
}
//或者空检测
if (n==null){
return;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
类型检测
//自动类型转换
如果一个不可变的局部变量或属性已经
判断出为某类型,那么检测后的分支中可以直接当作该类型使用,无需显式转换
//is,类型java中的instance of
public fun test2(view:View){
val str:String="你好啊";
val stringLength = getStringLength(str)
Log.d("meee","stringLength:"+stringLength)//3
}
//Any表示任意类型
fun getStringLength(obj:Any):Int?{
if (obj is String){
//类型判断后,则默认obj是判断的类型
return obj.length
}else {
return null;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
//反过来用也行
fun getStringLength2(obj:Any):Int?{
if (obj !is String){
//类型判断后,则默认obj是判断的类型
return null
}else {
return obj.length;
}
}
//会在判断条件&&右边自动转换
fun getStringLength3(obj:Any):Int?{
if (obj is String &&obj.length!=0){
return obj.length
}
return null
}
集合类的创建
var list:ArrayList<String> = ArrayList()//=前要有个空格,否则编译报错
For循环
fun testfor(view:View){
var list:ArrayList<String> = ArrayList()
val list2= listOf<String>("你好","你好","你好");
list.add("你好啊")
list.add("你好啊")
list.add("你好啊")
list(list)
//不包括100
for (i in 0 until 100){
Log.d("meee","哈哈"+i);//输出至哈哈99
}
}
fun list(list:ArrayList<String>){
//类似增强型for循环了
for(item in list){
Log.d("meee",item);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
When表达式
//类似switch
fun getItemName(index:Int):String{
when(index){
0 ->return "Zero"
1 ->return "One"
2 ->return "Two"
else->return "Null"//类似default
}
}
分号的作用
分割同一行的不同函数
Range
//使用in运算符来检测某个数字是否在指定区间内
fun testRange(view:View){
Log.d("meee","38:"+isIn39to50(38));//false
Log.d("meee","39:"+isIn39to50(39));//true
Log.d("meee","49:"+isIn39to50(49));//true
Log.d("meee","50:"+isIn39to50(50));//true
Log.d("meee","38:"+isNotIn39to50(38));//true
Log.d("meee","39:"+isNotIn39to50(39));//false
Log.d("meee","49:"+isNotIn39to50(49));//false
Log.d("meee","50:"+isNotIn39to50(50));//false
}
fun isIn39to50(num:Int):Boolean{
if (num in 39..50){
return true;
}
return false;
}
fun isNotIn39to50(num:Int):Boolean{
if (num !in 39..50){
return true;
}
return false;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
区间迭代
//区间迭代--------------------------------------------------------------------------------------
fun testRangeIterator(view:View){
//包括100,step表示间隔
for (x in 3 .. 100 step 1){
Log.d("meee","x:"+x);
}
//包括100,step表示间隔
for (x in 99 downTo 0 step 3){
Log.d("meee","y:"+x);
}
}
集合迭代
//集合迭代--------------------------------------------------------------------------------------
fun CollectionIterator(view:View){
val datas= setOf("apple","banana","pineApple")
for(data in datas){
Log.d("meee",""+data);
}
}
使用in判断集合中是否包含某元素
//使用 in 运算符来判断集合内是否包含某实例
when{
"apple" in datas -> Log.d("meee","已经买苹果啦");
"xxx" in datas -> Log.d("meee","并没有xxx");//没有打印
}
用Lambda对集合进行筛选
fun LambdaFilter(view:View){
val fruits = listOf("banana", "avocado", "apple", "kiwi")
fruits.filter { it.startsWith("a") }//筛选出以a开头的
.sortedBy { it }//排序
.map { it.toUpperCase() }//映射
.forEach{
Log.d("meee",it);//遍历
}
//过滤
val datas=fruits.filter { x-> x.startsWith("a") }
Log.d("meee","datas:"+datas);
//等价于
val datas2=fruits.filter { it.startsWith("a") }
Log.d("meee","datas2:"+datas2);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
类 抽象类 接口
//普通类
class Circle(val radius:Double){
fun getArea():Double=radius*radius*Math.PI
}
//抽象类
abstract class Shape(val sides:List<Double>){
abstract fun getArea():Double
val sideNum:Double get()=sides.sum()
}
//接口
interface IsColored{
val isColored:Boolean
}
//继承和实现
class Rectangle(
var height:Double,
var width:Double
):Shape(listOf(11.2,1.0)) ,IsColored{
override val isColored: Boolean=true
override fun getArea(): Double =height*width
}
class Triangle(var Height:Double
,var Width:Double
):Shape(listOf(11.1)),IsColored {
override val isColored: Boolean=true
override fun getArea(): Double=Height*Width
override fun toString(): String ="Triangle(Height=$Height, Width=$Width, isColored=$isColored,Sidenum=$sideNum)"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
//测试
fun newClass(view:View){
//创建对象
var circle=Circle(10.0)
Log.d("meee","circle:"+circle);//Circle(radius=10.0)
Log.d("meee","circle:"+circle.getArea());//314.1592653589793
val tri= Triangle(11.1,11.1)
Log.d("meee","tri:"+tri);//Triangle(Height=11.1, Width=11.1, isColored=true,Sidenum=11.1)
Log.d("meee","tri:"+tri.sideNum);//tri:11.1
Log.d("meee","tri:"+tri.getArea());//tri:123.21
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
函数的默认参数
fun noParamFunction(a:Int=0,b:Int=1)=a+b
用when关键字进行类型判断
fun testJudgeByWhen(obj:Any){
when(obj){
is String -> Log.d("meee","类型为string"+obj.length);
is Int -> Log.d("meee","类型为Int");
else -> Log.d("meee","unkonw");
}
}
遍历map(key-value)集合
fun listMap(v:View){
val map=HashMap<Int,String>()
map.put(1,"小黄")
map.put(2,"老江")
map.put(3,"灶杰")
Log.d("meee","map:"+map);
for((k,v) in map){
Log.d("meee","$k 映射 $v");
}
}
创建只读list map
//创建只读list map
fun readOnlyListAndMap(v:View){
val list= listOf<String>("1","2","3")
val map= mapOf<Int,Int>(1 to 100,2 to 300,3 to 1000)
}
ByLaze
fun ByLazy(v:View){
//第一次被调用时就被初始化,想要被改变只能重新定义,只能在val上使用
val str:String by lazy { "你好啊" }
Log.d("meee","str:"+str);
}
拓展函数
fun String.addFun(){
Log.d("meee","= =");
}
fun String.toLowerCase(){
Log.d("meee","= =");
}
fun extendFunction(view:View){
"你好啊".addFun()
//如果存在同名的方法,则默认以覆盖为准
"s".toLowerCase()//Log.d("meee","= =");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
单例
object SingleInstance{
val name="小黄"
}
fun singleInstance(v:View){
Log.d("meee","SingleInstance.name:"+SingleInstance.name);
Log.d("meee","SingleInstance:"+SingleInstance);
}
非空判断的缩写
//非空判断的缩写
fun notNull(v:View){
var str:String?=null
//非空判断执行对象的方法
str?.addFun()//不会执行addFun();
//if not null
val str2="12"
str2?.let {
Log.d("meee","str2不为空");
}
//if null
val str3:String?=null
str3?:Log.d("meee","str3为空");
//if not null and else
val obj=str?.length?:"空的"
Log.d("meee",""+obj);//"空的"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
以When表达式为返回值
fun returnWhen(v:View){
Log.d("meee",""+returnWhen("red"));
Log.d("meee",""+returnWhen("blue"));
Log.d("meee",""+returnWhen("unkonw"));
}
fun returnWhen(color:String):String{
return when(color){
"red" -> "红色"
"green" -> "绿色"
"blue" -> "蓝色"
else -> "找不到该颜色"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
try-cache表达式
fun tryCache(v:View){
var str=try {
throw RuntimeException("呵呵")
"你好啊"
}catch (e: RuntimeException){
}
Log.d("meee",""+(str==null));
}
对同一个对象调用多个方法>>With 关键字的使用
fun MutilMethodCall(v:View){
val tri=Tri()
with(tri){
//在with关键字内可以直接调用该对象的方法
for(x in 1..5){
add1()
add2()
add3()
}
}
}
class Tri(){
fun add1(){
Log.d("meee","side1");
}
fun add2(){
Log.d("meee","side2");
}
fun add3(){
Log.d("meee","side3");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
FileIo流的使用方法(亲测不行,找不到Files类)
val stream = Files.newInputStream(Paths.get("/some/file.txt"))
stream.buffered().reader().use { reader ->
println(reader.readText())
}
泛型返回值的使用
inline fun <reified T: Any> Gson.fromJson(json: JsonElement): T = this.fromJson(json,
T::class.java)
可空布尔值的使用
fun notBoolean(v:View){
val flag:Boolean?=null
if(flag==true){
Log.d("meee","true");
}else{
Log.d("meee","false or null");
}
}
同步方法
@Synchronized
fun getInstance():APP {
if(app==null){
app=APP()
}
return app as APP
}
静态方法
//companion object表示伴随object,也就是java的静态方法的意思
companion object{
var app: APP? = null
@Synchronized
fun getInstance():APP {
if(app==null){
app=APP()
}
return app as APP
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
Kotlin获取class方法
//亲测报错,ActivityNotFoundException
intent.setClass(context,NotepadActivity.javaClass)
// :: 操作符来获取指向特定对象实例的方法或属性的成员引用
intent.setClass(context,NotepadActivity::class.java)
抽象类的实现
val mAdapter = object : HolderAdapter<String, CommonViewHolder>(context, list, id) {
override fun bindDatas(holder: CommonViewHolder, data: String, position: Int) {
}
}