2021-05-03 Kotlin 异常等


/**

* 泛型:泛指任意类型

* 修饰函数:泛型函数

* 类:泛型类

*/

/**

* 使用out修饰的集合,只能接受指定类型的子类组成的集合

* out修饰的集合对象,只能取,不能存

* 型变

*/

/**

* 使用in修饰的集合,只能接受指定类型的父类类组成的集合

* in修饰的集合对象,只能存,不能取

*/

/**

* 修饰类:

* out:指定的类型只能作为返回值来获取

* in:指定的类型只能通过函数的参数传递进来

*/

// 1 2 3 4

//如果有把索引和元素返回

//如果没有返回-1和null

fun Array.findElement(element:T, func:(Int,T?) -> Unit){//Array的拓展函数findElement(这是个高阶函数)

    for (i in this.indices){//如果该数组中有和要找的元素一样的元素

if (this[i] == element){//执行函数func,参数是i和element

func(i,element)

return

        }

}

//没有

    func(-1,null)//执行函数func 参数是-1和null

}

fun test(){

val array1 =arrayOf(1,2,3,4,5,6)

val array2 =arrayOf("Jack","Rose","Marry")

array2.findElement("Jack"){ index, value->   //lambda表达式的参数名称

        println("$index$value")            //lambda表达式要执行的语句

}

}

class MyArray{

var contents =arrayListOf()

fun get(index:Int):T?{

if (indexin 0 until contents.size){

return contents[index]

}else{

return null

        }

}

fun add(e:T){

contents.add(e)

}

}

open class Old

open class Father:Old()

class Child:Father()

fun main() {

var childList:List =listOf()

var fatherList:List =listOf(Child())

val childArrayList:ArrayList =arrayListOf()

val fatherArrayList:ArrayList = childArrayList

//out:只能放置子类类型

    //in:只能放置父类类型

}


class Person{

var name:String =""

    var age:Int =0

    var weight:Float =0f

}

fun main() {

val pp = Person()

//正常访问方式

    pp.name ="Jack"

    pp.age =30

    pp.weight =150f

    //inline 内存资源  函数的参数是一个Lambda

    //查看also、apply、with、run、let的实现方式

    //let -> ?.let

    /**

    * 使用it引用外部对象

    * 返回值为 闭包/Lambda内部最后一行的结果

    */

    val result = pp.let {

        it.name ="Jack"

        it.age =30

        it.weight =150f

12

    }

    /**

    * ?.let 判断是否为空

    */

    val p:Person? =null

    p?.let {

        //.....安全

    }

    /**

* also

    * 当创建一个对象后,需要对这个对象进行额外操作

    * 返回值就是这个对象本身

    */

    //also -> object.also{}

    val p2 = Person().also {

        it.name ="Jack"

        it.age =18

        it.weight =150f

        println(it)

}

    //apply -> object.apply()

    /**

* apply

    * 当创建一个对象之后 需要对这个对象进行初始化

    * 闭包内部使用this来引用对象本身

    * 返回值就是对象本身

    */

    Person().apply {

        name ="Jack"

        age =8

        weight =150f

    }

}


/**

* 协程Coroutline

*

* 进程:正在运行的程序

* 线程:真正完成任务的单元、

*

*

* 线程的分配:操作系统为线程分配所需的内存资源

*            线程分配过多会导致内存溢出

*            OOM Out Of Memory

* 多线程:多个线程,执行多个任务

* 同步:A -> B -> C

* 异步:同时执行多个任务,CPU

* 同一时间,一个cpu只能执行一件事情,时间片分配

*

* 协程:轻量级的线程 JVM级别  几乎不耗任何资源

*

* Android中子线程不能操作UI  只能处理非UI的事物

*/

/**

* Job

* 记录当前协程运行状态(isActive isComplete  isCancel)

* start

* cancel

* resume

* join:等这个协程执行完毕

*

* launch和async开启任务的区别

* 不会阻塞当前线程

* launch返回的是Job

* async返回的是Deffered<T>:Job  T为操作之后得到的数据,使用await获取

*/

fun main()=runBlocking{

    println("start ${Thread.currentThread().name}")

val job =launch {

        val t =measureTimeMillis {

            task1()

task2()

}

        println(t)

}

    val data1 =async {

        //A

        "www.baidu.com/image/1.jpg"

    }

    val url = data1.await()

async {

        //B

        println("开始下载 $url")

//

        "1.jpg"

    }

  val scope =CoroutineScope(job + Dispatchers.Main)

scope.launch {

        ///

    }

    launch {

        task2()

}

    println("end ${Thread.currentThread().name}")

}

suspend fun task1(){

delay(2000)

}

suspend fun task2(){

delay(3000)

}



/**

* suspend

* 用于修饰函数,表示这个功能会阻塞主线程,挂起函数

* 挂起函数的调用只能在另外一个挂起函数或者协程中调用

* 不能在主线程中直接调用

*/

/**

* 如何开启一个协程

* CoroutineScope  协程域  有了这个,挂起函数才能执行,同一个域里面可以开启多个协程

* runBlocking  测试

* 默认会在当前线程上执行

*/

/**

* 如何切换协程运行环境

* withContext()

* Dispatchers

*          IO

*          Default

*          Main

*          Unconfined

*/

suspend fun download(){

withContext(Dispatchers.IO){

        println("C1 start ${Thread.currentThread().name}")

delay(1000)

println("C1 end ${Thread.currentThread().name}")

withContext(Dispatchers.Main){

            //更新UI

        }

}

}


/**

* 网络获取数据:Json -> 对象 -> 操作

* NewsModel

*          val total:Int

*          val data:List<>

* News

*          val uid:Int

*          val title:String

*          val time:Date

*

* Map("title":"广东夺冠了","pic":"易建联笑哈哈.jpg")

* Pairs

*/

fun main() {

val data =downloadData()

val obj =autoCreateInstance(data,Good::class)

}

fun autoCreateInstance(

data:Map>,

    clz:KClass

):Any?{

//获取这个类对应的数据

    val result = data[clz.simpleName]

//获取主构造函数

    val pconstr = clz.primaryConstructor

    //获取主构造函数的参数

    val valuesParameterArray =arrayOfNulls((pconstr?.parameters?.size)!!)

pconstr?.parameters.also {

        it?.forEach {parameter->

            //获取参数的名字

            val name = parameter.name!!

val value = result?.get(name)

valuesParameterArray[parameter.index] = value

}

}

    //创建对象

    return pconstr?.call(*valuesParameterArray)

}

fun downloadData():Map> {

/**

    * key-value 键值对

    */

    val news =mapOf(

Pair("title","广东夺冠了"),

        Pair("pic","易建联笑哈哈.jpg")

)

val goods =mapOf(

Pair("name","防晒霜"),

        Pair("price","500"),

        Pair("num","100")

)

val results =mapOf(

"News" to news,

        "Good" to goods

)

return results

}

data class News(val title:String,val Pic:String)

data class Good(val name:String,val price:String,val num:String)


/**

* 异常处理 简单且重要

* try - 具体可能出现bug的代码

* catch - 捕获可能的异常

* finally - 最终都会执行的代码

*

*

* 异常的类Exception

*/

自己定义一个异常类

以下是灵活写法

class SomethingHappenException(message:String): Exception(message){

}

fun main() {

if (2 >1){

throw SomethingHappenException("自己写的某些异常信息...")

}

写死了:

class SomethingHappenException(): Exception("自己写的某些异常信息..."){

}

fun main() {

if (2 >1){

throw SomethingHappenException()

}

try {

val num =readLine()?.toInt()

println(num)

}catch (e:Exception){

println("捕获异常了:${e.message}")

}finally {

println("处理结果")

}

}

意义:纵使bug发生,程序也可以继续运行下去

小技巧:如果在catch时不知道具体是什么异常,没有学过,就写这个异常的父类,Exception,里面就囊括了所有异常的类型

StackTrace:跟踪所有执行的方法 会把所有已经执行的方法、在哪一步出错这些信息打印出来

message:程序不会崩溃 而是得到了具体的异常(比StackTrace更加精准)

异常出现了就不执行try接下来的语句 而是直接调到catch部分

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • [TOC] 简介 Coroutines are computer program components that ...
    Whyn阅读 5,894评论 5 15
  • 一、前言- 1.为什么要学kotlin?- 2.准备工作 二、kotlin基础语法- 2、函数- 3、条件控制- ...
    会思考的鸭子阅读 2,880评论 7 36
  • 前言 在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言。 ...
    玖玖君阅读 659评论 0 0
  • #Kotlin之班门弄斧 ##面向对象 ##java和kotlin的交互 ##协程及协程框架 ## 面向对象 ...
    束发_d7a8阅读 302评论 0 0
  • 为什么要搞出和用协程呢 是节省CPU,避免系统内核级的线程频繁切换,造成的CPU资源浪费。好钢用在刀刃上。而协程是...
    静默的小猫阅读 625评论 0 2