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: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部分

你可能感兴趣的:(2021-05-03 Kotlin 异常等)