全部 文章 问答 分享 共找到227个相关内容
[分享] Rxjava源码阅读指南
本文不对Rxjava的基本使用进行讲解,仅对源码做分析,如果你对Rxjava的基本使用还有不清楚的,建议学习官方文档之后再阅读本文 本文会逐一解析Rxjava的create()、subscribe
2020-02-06 12:39 · Android / RxJava / 源码 / 异步
[文章] 《Kotlin 核心编程》阅读笔记
@[TOC](《Kotlin核心编程》阅读笔记)第四章代数数据类型和模式匹配代数数据类型(ADT)在计算机编程中,特别是函数式编程与类型理论中,ADT是一种组合类型(compositetype)。
1970-01-01 00:00 · kotlin
[文章] CSS如何实现文章展开阅读全文的效果?
CSS如何实现文章展开阅读全文的效果?很多网站都有这样的功能?我也不知道为什么需要这个功能,展开阅读。先是只能见一部分。
2020-03-06 15:10 · 前端 / CSS / 阅读全文
[文章] Android学习笔记——记住密码的功能实现(一)
今天跟大家分享一篇安卓的学习笔记,就是登录时,记住密码的功能实现。想必大家应该都知道记住密码功能吧。比如QQ,微信,这些常用软件。即第一次登录后就不需要再重复输入账号密码进行登录操作。
2020-04-12 22:32 · Android
[文章] 【领券联盟】笔记:视频46,47,48,49-解决刷新控件的事件冲突问题
好吧...)运行app,根据提示解决一些剩下的小问题最后把TbNestedScrollView移到refreshlibrary中课堂笔记大概意思:TwinklingRefreshLayout是通过拦截事件处理加载更多的
2020-04-02 19:41 · 课堂笔记
[文章] 《kotlin核心编程》阅读笔记 第九章 设计模式
@[TOC](《kotlin核心编程》阅读笔记第九章设计模式)第九章设计模式基于Kotlin崭新的语言特性,实现或替换了Java中部分典型设计模式。
1970-01-01 00:00 · kotlin
[文章] 《深入理解Java虚拟机》阅读笔记-1
粗略笔记1.虚拟机介绍虚拟机家族SunClassicHostSPotVM经典虚拟机Mobile/EmbeddedVM移动端/嵌入式使用BEAJRockit/IBMJ9VMBEA/IBM公司自有虚拟机..
2022-10-29 21:50 · java / 虚拟机 / 阅读笔记
[文章] Android学习笔记——记住密码的功能实现(二)
工具类里面需要一个静态的存放数据的方法,一个获取数据的Map集合方法3.在登录界面的登录按钮点击事件中通过工具类调用存放方法获取并存放数据,在onCreate方法中通过工具类调用获取数据的方法,将数据展示在文本框OK,那么笔记就分享到这里
2020-04-13 09:42 · Android
[问答] 有关记笔记的问题

编程也算学了一些,今天静下心来想想,发现自己记笔记的习惯好像很差:“跟着视频学习的时候,总是把所有的知识点,基本完完全全都记了下来,甚至是官方文档中有的内容,或者视频作者的笔记,自己也会再敲一遍”

2023-03-31 20:31 · 笔记 / 学习
[问答] Jetpack我们从MVVM开始37的课程笔记,我在阳光沙滩-课程笔记怎么找不到啊

Jetpack我们从MVVM开始37的课程笔记,我在阳光沙滩-课程笔记怎么找不到啊,

2022-05-30 09:10 · 安卓

[问答] 课程笔记

为啥每个课程点进去 都没有笔记呢 只有章节

2021-09-02 22:35 · 安卓 / 自定义控件
[文章] 安卓端sob_blog解析阅读MarkDown文章
作为一名学习安卓的小菜鸡,自然希望在安卓上也能阅读我们写的文章。所以如果能在安卓上显示MarkDown,那可真是太爽了。考虑到前几天大锯老师在VUE里面引入了一个mavon-editor的库。
2020-08-09 17:13 · 安卓 / markDown / 源码
[问答] 有Android课堂笔记

有Android课堂笔记

2022-06-14 09:12 · 寻找笔记 / Android
[问答] 求视频中的后端笔记
求后端课程视频中使用md写的笔记
2020-09-07 14:25 · 后台
[文章] 【领券联盟】笔记:视频108~113-实现扫码功能【完结】
课堂笔记实现灰色UI在BaseActivity创建时把最外层View饱和度设置为0//黑白风格ColorMatrixcm=newColorMatrix();cm.setSaturation(0);Paintpaint
2020-04-11 00:26 · 读书笔记
[文章] 学习笔记-POI与EasyExcel
格式规范newXSSFWorkbook()以.xlsx结尾FileOutputStreamfileOutputStream=newFileOutputStream("F:\\Desktop\\笔记
2021-08-26 13:35 · POI / EasyExcel / 数据导出 / 数据导入
[问答] SOB首页导航栏的笔记模块咋没了?

SOB首页导航栏的笔记模块咋没了?

2022-07-22 17:13 · SOB导航 / 笔记
[问答] 在论坛里找不到视频中提到的文章和课堂笔记
在B站看到视频,笔记做的都非常好,但是光看视频效率比较低。视频中提到论坛中有笔记和文章,但为什么找不到...https://bbs.sunofbeaches.com/网站也上不去
2019-10-30 00:20 · 安卓
[文章] 《Kotlin》阅读笔记 第八章 元编程
@TOC第八章元编程Java的反射只是元编程的一种方式。示例:将dataclass转换成Map的例子。dataclassUser(valname:String,valage:Int){funtoMap(a:User):Map<String,Any>{returnhashMapOf("name"toname,"age"toage)}}这样实现有一个缺点:对每一个新的类型我们都需要重复实现toMap函数,因为每个类型都拥有不同的属性。程序和数据通过反射实现:dataclassUser(valname:String,valage:Int){funtoMap():Map<String,Any>{returnhashMapOf("name"toname,"age"toage)}}objectMapper{fun<A:Any>toMap(a:A):Map<String,Any?>{//获取A中的所有属性returna::class.memberProperties.map{m->valp=masKProperty<*>p.nametop.call(a)}.toMap()}fun<A:Any>toMap1(a:A)=run{//获取A中的所有属性a::class.memberProperties.map{m->valp=masKProperty<*>p.nametop.call(a)}.toMap()}}funmain(){for(entry1inUser("Kar",19).toMap()){println("${entry1.key}---->${entry1.value}")}for(entryinMapper.toMap(User("Jack",20))){println("${entry.key}---->${entry.value}")}for(entryinMapper.toMap1(User("Tom",18))){println("${entry.key}---->${entry.value}")}}上面代码中的两个toMap方法,是类似的。这里的a::class的类型是KClass,是Kotlin中描述类型的类型(也称为metaclass);在传入参数类型为User时,a::class则可以描述User类型的数据。这样描述数据的数据就称为元数据。什么是元编程操作元数据的编程就是元编程。程序即是数据,数据即是程序。这句话包含两个意思:前半句指的是访问描述程序的数据,如我们通过反射获取类型信息。后半句则是指:将这些数据转化成对应的程序,也就是所谓的代码生成。元编程就像高阶函数一样,是一种更高阶的抽象,高阶函数将函数作为输入或输出,而元编程则是将程序本身作为输入或输出。常见的元编程技术运行时通过API暴露程序信息反射;动态执行代码多见于脚本语言。如JavaScript就有eval函数,可以动态地将文本作为代码执行。通过外部程序实现目的如编译器,在将源文件解析成AST之后,可以针对这些AST做各种转化。这种实现思路最典型的例子是我们常常谈论的语法糖,编译器会将这部分代码AST转化为相应的等价的AST,这个过程通常被称为desuger(解语法糖)。AST:抽象语法树是源代码语法结构的一种抽象表示;它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每一个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句可以使用带有两个分支的节点来表示。反射,有时候也称为自反,是指元语言(即前文提到的描述程序的数据结构)和要描述的语言是同一种语言的特性。除了运行时反射之外,也有许多语言支持编译期反射,编译期反射通常需要宏等技术结合实现,编译器将当前程序的信息作为输入传入给宏,将其结果作为程序的一部分。宏:Koltin不支持宏。模板元编程:和Kotlin关系并不大。Kotlin的反射kotlin和Java反射Kotlin的KClass和Java的Class可以看作同一个含义的类型,并且通过.java和.kotlin方法在KClass和Class之间相互转化。Kotlin中的KCallable和Java的AccessiableObject都可以理解为可调用元素。Java中构造方法为一个独立的类型,而Kotlin则统一作为KFunction处理。Koltin中的KProperty和Java的Filed不太相同,Koltin的KProperty通常指相应的Getter和Setter(只有可变属性Setter)整体作为一个KProperty(通常情况Kotlin并不存在字段的概念),而Java的Field通常仅仅指字段本身。koltin的KClassKCLass的特别属性或函数特别属性或函数|含义--------|-----isCompanion|是否伴生对象isData|是否数据类isSealed|是否密封类objectInstance|object实例(如果是object)companionObjectInstance|伴生对象实例declareMemberExtensionFunctions|扩展函数declareMemberExtensionProperties|扩展属性memberExtensionFunction|本类及超类扩展函数memberExtensionProperties|本类及超类扩展属性starProjectedType|泛型通配类型示例:获取object实例sealedclassNat{companionobject{objectZero:Nat()}valCompanion._0get()=Zerofun<A:Nat>Succ<A>.proceed():A{returnthis.prev}}dataclassSucc<N:Nat>(valprev:N):Nat()fun<A:Nat>Nat.plus(other:A):Nat=when{otherisSucc<*>->Succ(plus(other.prev))else->this}funmain(){println(Nat.Companion::class.isCompanion)//trueprintln(Nat::class.isSealed)//trueprintln(Nat.Companion::class.objectInstance)//chapter8.Nat$Companion@646be2c3println(Nat::class.companionObjectInstance)//chapter8.Nat$Companion@646be2c3println(Nat::class.declaredMemberExtensionFunctions.map{it.name})//[proceed]println(Nat::class.declaredMemberExtensionProperties.map{it.name})//[_0]'println(Succ::class.declaredMemberExtensionProperties.map{it.name})//[]println(Succ::class.declaredMemberExtensionFunctions.map{it.name})//[]println(Succ::class.declaredMemberExtensionProperties.map{it.name})//[]println(Succ::class.memberExtensionProperties.map{it.name})//[_0]println(Succ::class.memberExtensionFunctions.map{it.name})//[proceed]println(Succ::class.starProjectedType)//chapter8.Succ<*>println(Nat::class.memberExtensionFunctions.map{it.name})//[proceed]}kotlin的KCallable如何获取Class的成员:通过members方法,它的返回值是一个Collection<KCallable<*>>。KCallable提供的APIKCallable提供的API|含义--------|-----isAbstract:Boolean<KParameter>|此KCallable是否为抽象的isFinal:Boolean|此KCallable是否为finalisOpen:Boolean|此KCallable是否为openname:string|此KCallable的名称parameters:List<KParameter>|调用此KCallable需要的参数returnType:KType|此KCallable的返回类型typeParameters:List<KTypeParameter>|此KCallable的类型参数visibility:KVisibility?|此KCallable的可见性call(varargargs:Any?):R|给定参数调用此KCallablefunmain(){val_1=Succ(Nat.Companion.Zero)valpreceed=_1::class.members.find{it.name=="proceed"}println(preceed?.call(_1,_1)==Nat.Companion.Zero)}上面代码通过反射执行Succ的扩展函数proceed,这里传入了两个Nat对象,因为执行扩展函数时,除了参数实例外,需要传入接受者实例。在Kotlin中,并不是所有的属性都是可变的,因此我们只能对那些可变的属性进行修改操作。KMutableProperty是KProperty的一个子类。使用When表达式来识别属性。dataclassPerson(valname:String,valage:Int,varaddress:String)funKMutablePropertyShow(){valp=Person("YanLq",22,"SWPU")valprops=p::class.memberPropertiesfor(propinprops){when(prop){isKMutableProperty<*>->prop.setter.call(p,"DZ")else->prop.call(p)}}println(p.address)}funmain(){KMutablePropertyShow()}获取参数信息Koltin把参数分为3个类别,分别是函数的参数(KParameter),函数的返回值(KType)以及类型参数(KTypeParameter)KParameter使用KCallable.parameters即可获取一个List<KParameter>,它代表的是函数(包括扩展函数)的参数。API描述index:Int返回该参数在参数列表里面的indexisOptiona:Boolean该参数是否为OptionalisVarags:Boolean该参数是否为varagskind:Kind该参数的kindname:String?该参数的名称type:KType该参数的类型funKParameterShow(){for(cinPerson::class.members){print("${c.name}->")for(pinc.parameters){print("${p.type}--")}println()}}funmain(){KParameterShow()}KType获取KCallable的返回值类型。每一个KCallable都可以使用returnType来获取返回值类型,它的结果类型是KType。API描述arguments:List<KtypeProjection>该类型的类型参数classifier:KClassifier该类型在类声明层面的参数,如该类型为List<String>,那么通过classifier得到结果为List(忽略类型参数)isMarkedNullable:Boolean该类型是否标记为可空类型dataclassPerson(valname:String,valage:Int,varaddress:String){funfriendsName():List<String>{returnlistOf("Yison","Jilen")}}funmain(){Person::class.members.forEach{println("${it.name}->${it.returnType.classifier}")}}>>>address->classkotlin.Stringage->classkotlin.Intname->classkotlin.Stringcomponent1->classkotlin.Stringcomponent2->classkotlin.Intcomponent3->classkotlin.Stringcopy->classchapter8.Personequals->classkotlin.BooleanfriendsName->classkotlin.collections.ListhashCode->classkotlin.InttoString->classkotlin.StringclassifierAPI其实就是获取该参数在类层面对应的类型。KTypeParameter对于函数和类来说,还有一个重要的参数——类型参数,在KClass和KCallable中我们可以通过typeParameters来获取class和callable的类型参数,它的返回结果集是List<KTypeParameter>,不存在类型参数时就返回一个空的List。dataclassPerson(valname:String,valage:Int,varaddress:String){funfriendsName():List<String>{returnlistOf("Yison","Jilen")}fun<A>get(a:A):A{returna}}funKTypeParameterShow(){for(cinPerson::class.members){if(c.name.equals("get")){println(c.typeParameters)}}vallist=listOf<String>("How")println(list::class.typeParameters)}funmain(){KTypeParameterShow()}>>>[A][E]Kotlin注解Kotlin的注解创建语法:annotationclassFooAnnotation(valbar:String)注解koltin.Metadata这是实现Kotlin大部分独特特性反射的关键,Koltin将这些信息直接以注解形式存储在字节码文件中,以便运行时发射可以获取这些数据。和Java一样注解的参数只能是常量,并且仅支持下列类型:与Java对应的基本类型字符串Class对象(KClass或者Java的Class)其他注解上述类型数组。基本类型数组需要指定为对应的XXXArray,如:IntArray而不是Array<Int>/标注在注解上的注解我们称之为元注解。Java有下列5个元注解。-Documented文档(通常是API文档)中必须出现给注解。-Inherited如果超类标注了该类型,那么其子类型也将自动标注该注解而无需指定。-Repeatable这个注解在同一位置可以出现多次。-Retention表述注解用途。有三种取值。-Sourc仅在源代码中存在,编译后的class文件不包含该注解信息。-CLASSclass文件中存在该注解,但不能被反射读取。-RUNTIME注解信息同样保存在class文件中并且可以在运行时通过反射获取。-Target表明注解可应用于何处。Kotlin也有相应类似的元注解在kotlin.annotation包下。Kotlin和Java的注解整体上保持一致。Koltin目前不支持Inherited。无处不在的注解Kotlin(AnnotationTarget)Java(Target)说明CLASSTYPE作用于类ANNOTATION_CLASSANNOTATION_TYPE作用于注解本身(即元注解)TYPE_PARAMETERTYPE_PARAMETER作用于类型参数PROPERTYNA作用于属性FIELDFIELD作用于字段(属性通常包含字段Getter以及Setter)LOCAL_VARIABLELOCAL_VARIABLE作用于局部变量VALUE_PARAMETERNA作用于val参数CONSTRUCTORCONSTRUCTOR作用于构造函数FUNCTIONMETHOD作用于函数(Java只有method)PROPERTY_GETTERNA作用于GetterPROPERTY_SETTERNA作用于SetterTYPETYPE_USE作用于类型EXPRESSIONNA作用于表达式FILEPACKAGE作用于文件开头/包声明TYPEALIASNA作用于类型别名annotationclassCache(valnamespace:String,valexpires:Int)annotationclassCacheKey(valkeyName:String,valbuckets:IntArray)@Cache(namespace="hero",expires=3600)dataclassHero(@CacheKey(keyName="heroName",buckets=intArrayOf(1,2,3))valname:String,valattack:Int,valdefense:Int,valinitHp:Int)精准控制注解位置假设我们有注解annotationclassCacheKey。精准的注释控住语法:用法|含义-|-@file:CacheKey|CacheKey注解作用于文件@property:CacheKey|CacheKey注解作用于属性@field:CacheKey|CacheKey注解作用于字段@get:CacheKey|CacheKey注解作用于Getter@set:CacheKey|CacheKey注解作用于Setter@receiver:CacheKey|CacheKey注解作用于扩展函数或属性@param:CacheKey|CacheKey注解作用于构造函数参数@setParam:CacheKey|CacheKey注解作用Setter的参数@delegate:CacheKey|CacheKey注解作用于存储代理实例的字段@Cache(namespace="hero",expires=3600)dataclassHero(@property:CacheKey(keyName="heroName",buckets=[1,2,3])valname:String,@field:CacheKey(keyName="atk",buckets=[1,2,3])valattack:Int,@get:CacheKey(keyName="def",buckets=[1,2,3])valdefense:Int,valinitHp:Int)获取注解信息代码标记上注解以后,注解本身也成为了代码的一部分。我们可以获取注解信息。通过反射获取注解信息但是前提是这个注解的Retention标注为Runtime或者没有显示注定(默认为Runtime)。annotationclassCache(valnamespace:String,valexpires:Int)annotationclassCacheKey(valkeyName:String,valbuckets:IntArray)@Cache(namespace="hero",expires=3600)dataclassHero(@CacheKey(keyName="heroName",buckets=[1,2,3])valname:String,valattack:Int,valdefense:Int,valinitHp:Int)funmain(args:Array<String>){valcacheAnnotation=Hero::class.annotations.find{itisCache}asCache?println("namespace->${cacheAnnotation?.namespace}")println("expires->${cacheAnnotation?.expires}")}>>>namespaceheroexpires3600通过反射获取注解信息是在运行时发生的。注解标准位置也会影响注解信息的获取。注解处理器JSR269引入了注解处理器(annotationprocessors),允许在编译过程中挂钩子实现代码生成,得益于此,如dagger之类的框架实现了编译时依赖注入这样原本只能通过运行时反射支持的特性。importjavax.annotation.processing.AbstractProcessorimportjavax.annotation.processing.RoundEnvironmentimportjavax.lang.model.element.ElementKindimportjavax.lang.model.element.TypeElementimportkotlin.reflect.full.memberPropertiesannotationclassMapperAnnotationclassMapperProcessor:AbstractProcessor(){privatefungenMapperClass(pkg:String,clazzName:String,props:List<String>):String{return"""package$pkgimportjava.utils.*;publicclass${clazzName}Mapper{publicMap<String,Object>toMap($clazzNamea){Map<String,Object>m=newHashMap<String,Object>();${props.map{"m.put(\"${it}\",a.${it})"}}}}""".trimIndent()}overridefunprocess(annotations:MutableSet<outTypeElement>?,roundEnv:RoundEnvironment?):Boolean{valel=roundEnv?.getElementsAnnotatedWith(MapperAnnotation::class.java)?.firstOrNull()if(el?.kind==ElementKind.CLASS){valpkg=el.javaClass.`package`.namevalcls=el.javaClass.simpleNamevalprops=el.javaClass.kotlin.memberProperties.map{it.name}valmapperClass=genMapperClass(pkg,cls,props)valjfo=processingEnv.filer.createSourceFile("${cls}Mapper")valwriter=jfo.openWriter()writer.write(mapperClass)writer.close()}returntrue}}我还不太会注解。不知道咋运行。
1970-01-01 00:00 · kotlin
[文章] 使用Gitee搭建免费图床配合typora写笔记也太爽了
使用Gitee搭建免费图床配合typora写笔记也太爽了正如拉大锯大佬所说typora,程序员的markdown编写工具,这是我用过最好用的了!
2021-01-11 15:34 · typora / 免费图床 / 笔记工具
[文章] 《Kotlin核心编程》阅读笔记 第七章 多态和扩展
@TOC第七章多态和扩展Kotlin的扩展其实多态的一种表现形式。多态的不同方式多态是面向对象程序设计的一个重要特性。当用一个子类继承一个父类的时候,这就是子类型多态(Subtypepolymorphism)。另一种熟悉的多态是参数多态(Parametricpolymorphism)。子类型多态用子类型替换超类型实例的行为,就是子类型多态。参数多态理解起来像是把参数抽成一个类型,类似泛型的感觉。对第三方进行扩展即扩展函数。扩展属性和扩展方法的实现是运行在类的实例上,不会修改类本身。特设多态和运算符重载特设多态:一个多态函数是有多个不同的实现,依赖于其实参而调用相应版本。operator:将一个函数标记为重载一个操作符或者和实现一个约定。dataclassArea(valvalue:Double)operatorfunArea.plus(that:Area):Area{returnArea(this.value+that.value)}funmain(){println(Area(1.0)+Area(2.0))}还可以重载减法minus、乘法times、除法div等扩展:为别的类添加方法、属性扩展与开放封闭原则软件实体应该是可扩展,而不可修改的。开放封闭原则开放封闭原则(OCP:OpenClosedPrinciple)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为了实现这一目标服务的,例如以替代原则实现最佳、正确的继承层次,就能保证不会违背开放封闭原则。使用扩展函数、属性funMutableList<Int>.exchange(fromIndex:Int,toIndex:Int){valtmp=this[fromIndex]this[fromIndex]=this[toIndex]this[toIndex]=tmp}这里扩展函数体里的this代表的是接收者类型的对象。标准库中的扩展函数:run、let、also、takeIfrunrun方法的定义:publicinlinefun<T,R>T.run(block:T.()->R):R=block()run是任何类型T的通用扩展函数,run中执行了一个返回值类型为R的扩展函数block,最终返回扩展函数的结果。let定义:publicinlinefun<T,R>T.let(block:(T)->R):R=block(this)let返回的是闭包里面的值。dataclassStudent(age:Int)classKot{valstudent:Student?=getStu()fundealStu(){valresult=student?.let{println(it.age)it.age}}}also定义:publicinlinefun<T>T.also(block:(T)->Unit):T{block(this)returnthis}函数的返回值是该函数的接收者。classKot{valstudent:Student?=getStu()fundealStu(){valresult=student?.also{stu->this.age+=stu.ageprintln(this.age)println(stu.age)this.age}}}takeIf如果我们不仅仅只想判断空,还想加入条件,这是let可能显得有点不足。定义:publicinlinefun<T>T.takeIf(predicate:(T)->Boolean):T?=if(predicate(this))thiselsenull当接收器满足某些条件才会执行。把之前的也写一下:with和applywith的定义:inlinefun<T,R>with(receiver:T,block:T.()->R):Rwith的第一个参数为接收者类型,然后通过第二个参数创建这个类型的block方法。apply的定义:inlinefun<T>T.apply(block:T.()->Unit):T看这些定义还是有点晕的。写代码时,在编译器的提示感觉会好点。
1970-01-01 00:00 · kotlin
[文章] SQL语句for Android Sqlite(视频+笔记+图解)
话不多话,具体看视频吧,笔记也不贴出來了,在网盘里直接下载。思维导入如下:其他的,内容就去下载吧。后话:一定要自己动手做,否则真的学不到的。我知道你一定能听懂,一定能理解是怎么回事。
2019-10-21 14:02 · sql / mysql / 数据库
[文章] 《Kotlin核心编程》阅读笔记 第五章 类型系统
第五章类型系统null引用在Java中如何解决空指针异常:函数内对于无效值,更倾向于抛异常处理。采用@NotNull/@Nullable标注使用专门的Optional对象对可能为null的变量就行装箱。可空类型在Kotlin中,可以在任何类型后面加上“?"Int?等同于Intornull由于null只能被存储在Java的引用类型中,所以在Kotlin中基本数据类型的可空版本都会使用该类型的包装形式,同样,如果使用基本数据类型作为泛型类的类型参数,Koltin同样会使用该类型的包装类。-安全调用"?."XXX?.YYY:当XXX不为null,才调用YYY-Elvis操作符"?:"或合并操作符。-非空断言"!!"类型检查:在Koltin中用is代替Java中的instanceof当类型需要强制转换时,可以利用"as"操作符来实现。Any:非空类型的根类型Kotlin把Java方法参数和返回类型中用到的Object类型看作Any(更确切的说是当作“平台类型”);Any?:所有类型的根类型。Nothing与Nothing?:Kotlin类型层级结构的最底层是Nothing类型。Nothing是没有实例的类型,Nothing类型的表达式不会产生任何值。它只能包含一个值“null”。自动装箱和拆箱Kotlin中的Int类型等同于int;Kotlin中的Int?等同于Integer;Kotlin中有Array,但是并不是一种原生的数据结构,而是一种Array类。甚至我们可以将Kotlin中的Array视作为集合类的一部分。Kotlin中还为原始类型额外引入了一些实用类:IntArray,CharArray,ShortArray等。分别对应了Java中的int[]、char[]、short[].IntArray等并不是Array的子类。Kotlin对原始类型有特殊优化,推荐使用原始类型数组。泛型将参数的类型进行参数化。泛型的优势:类型检查,能在编译时就帮你检查出错误。更加语义化,比如声明一个List<String>,便可以知道里面存储的是String对象,自动类型转换,获取数据时不需要进行类型强制转换;能写出更加通用的代码。在Kotlin中使用泛型的格式也是<T>,<S>类似的。声明一个泛型类和泛型函数:实现定义一个find方法,传入一个对象,若列表中存在该对象,就返回该对象,不存在则返回空;classSmartList<T>:ArrayList<T>(){funfind(t:T):T?{valindex=super.indexOf(t)returnif(index>=0)super.get(index)elsenull}}funmain(){valsmartList=SmartList<String>()smartList.add("qq")println(smartList.find("qq"))println(smartList.find("aa"))}除了上述做法,还可以有扩展函数;funmain(){valarrayList=ArrayList<String>()arrayList.add("qq")println(arrayList.find("qq"))println(arrayList.find("aa"))}fun<T>ArrayList<T>.find(t:T):T?{valindex=this.indexOf(t)returnif(index>=0)this[index]elsenull}类型约束:设定类型上界;示例;需求为:有一把刀只能用来切长在地上的水果(如西瓜)interfaceGround{}openclassFruit(valweight:Double)classApple(weight:Double):Fruit(weight)classBanana(weight:Double):Fruit(weight)classFruitPlate<T:Fruit>(valt:T)//:类型约束,表示只能装水果的盘子classWatermelon(weight:Double):Fruit(weight),Groundfun<T>cut(t:T)whereT:Fruit,T:Ground{println("Youcancut")}funmain(){cut(Watermelon(5.0))}通过where关键字,他可以实现泛型参数类型添加多个约束条件。上面的泛型是在静态时的行为,也就是Kotlin代码编译阶段关于泛型的知识点。publicclassTestArray{publicstaticvoidmain(String[]args){Apple[]applyArray=newApple[10];Fruit[]fruitArray=applyArray;//fruitArray[0]=newBanana(0.5);List<Apple>appleList=newArrayList<Apple>();//List<Fruit>fruitList=appleList;System.out.println(applyArray.getClass());System.out.println(appleList.getClass());}}>>>class[Lchapter5.Apple;>>>classjava.util.ArrayList数组是协变的,而List是不变的。简单来说就是Object[]是所有对象数组的父类,而List<Object>却不是List<T>的父类。从上面的打印结果可以知道,数组在运行时是可以获取自身的类型,而List<Apple>在运行时只知道自己是一个List,而无法获取泛型参数的类型。而Java数组是协变的,也就是说任意的类A和类B,若A是B的父类,则A[]也是B[]的父类。但是假如给数组加入泛型后,将无法满足数组协变的原则,因为在运行时无法知道数组的类型。Kotlin中的泛型机制和Java中是一样的,上面的特性Kotlin中也存在。类型擦除:Java受限于先后兼容的困扰,使用了类型擦除来实现了泛型,但是它还是通过其他方式来保证了泛型的相关特性。泛型在编译后是会擦除泛型类型的,而泛型的一些相关特性,比如类型检查是在编译器在编译前就会帮我们进行类型检查,类型自动转换是通过强制类型转化来实现的。类型擦除的矛盾:在某些场景需要知道运行时泛型参数类型。既然编译后会擦除泛型参数类型,那我们是不是可以主动指定参数类型来达到运行时获取泛型参数类型的效果呢?funmain(){valapplePlate=Plate(Apple(1.0),Apple::class.java)applePlate.getType()}openclassPlate<T>(valt:T,privatevalclazz:Class<T>){fungetType(){println(clazz)}}使用这种方法确实可以到达运行时获取泛型类型参数的效果,但是这样也有限制。vallistType=ArrayList<String>()::class.java//不被允许还可以使用匿名内部类来是实现。funmain(){vallist1=ArrayList<String>()vallist2=object:ArrayList<String>(){}println(list1.javaClass.genericSuperclass)println(list2.javaClass.genericSuperclass)}>>>java.util.AbstractList<E>java.util.ArrayList<java.lang.String>现在可以设计一个能获取到所有类型信息的泛型类:importjava.lang.reflect.ParameterizedTypeimportjava.lang.reflect.TypeopenclassGenericsToken<T>{vartype:Type=Any::class.javainit{valsuperClass=this.javaClass.genericSuperclasstype=(superClassasParameterizedType).actualTypeArguments[0]}}funmain(){valgt=object:GenericsToken<Map<String,String>>(){}println(gt.type)}Gson也是使用的类似方法。在Kotlin中除了用这种方式来获取泛型参数类型以外,还有另一种方式——内联函数。Kotlin中的内联函数在编译的时候编译器便会将相应函数的字节码插入调用的地方。Java并不支持主动指定一个函数是否是内联函数,所有在Kotlin中声明的普通内联函数可以在Java中调用,因为他不会被当做一个常规函数;而用reified来实例化的参数类型的内联函数则不能在Java中调用,因为它永远是需要内联的。打破泛型不变Kotlin中的List与Java的List有区别虽然都叫List,也同样支持泛型,但是Kotlin中的List定义的泛型参数前面多了一个out关键字。这个关键字就对这个List的特性起到了很大作用。普通方式定义的泛型是不变的,简单来说就是不管类型A和类型B是什么关系,Generic<A>与Generic<B>(Generic代表泛型类)都没有任何关系。在Java中String是Object的子类型,但是List<String>并不是List<Object>的子类型。在Kotlin中泛型的原理是一样的。但是,Kotlin的List为什么允许List<String>赋值给List<Any>呢?一个支持协变的List如果在定义泛型类和泛型方法的泛型参数前面加上out关键词,说明这个泛型类及泛型方法是协变的。类型A是类型B的子类型,那么Generic<A>也是Generic<B>的子类型。因为Kotlin的List支持协变,所以他无法添加元素,只能从里面读取内容;List一旦创建就不能再被修改。这便是将泛型声明为协变需要付出的代价。通常情况下,若一个泛型类Generic<outT>支持协变,那么它里面的方法的参数类型就不能使用T类型,因为一个方法的参数不允许传入参数父类型的对象,可能会导致错误。可以添加**@UnsafeVariance**注解来解除这个限制。一个支持逆变的Comparator逆变:类型A是类型B的子类型,但是Generic<B>反过来又是Generic<A>的子类型。加上现在需要对一个**MutableList<Double>**进行排序,利用其sortWith方法,我们需要传入一个比较器:valdoubleComparator=Comparator<Double>{d1,d2->d1.compareTo(d2)}funmain(){valdoubleList=mutableListOf(2.0,3.0)doubleList.sortWith(doubleComparator)for(iindoubleList){print("$i")}}但是如果又需要对MutableList<Int>,**MutableList<Long>**等进行排序,那我们可能又需要定义不同的Comparator。试想定义一个比较器,给这些列表用,这些数字类的共同父类是Number类。valnumberComparator=Comparator<Number>{num1,num2->num1.toDouble().compareTo(num2.toDouble())}funmain(){valdoubleList=mutableListOf(2.0,3.0)doubleList.sortWith(numberComparator)for(iindoubleList){print("$i")}println()valintList=mutableListOf(5,1)intList.sortWith(numberComparator)for(iinintList){print("$i")}}结果是成功运行了,这说明是可以这样做的。publicfun<T>kotlin.collections.MutableList<T>.sortWith(comparator:kotlin.Comparator<inT>/*=java.util.Comparator<inT>*/):kotlin.Unit{/*compiledcode*/}这里又出现了一个in关键词、和out类似,它也是泛型有个另一个特性——逆变:类型A是类型B的子类型,但是Generic<B>反过来又是Generic<A>的子类型。用out关键字声明的泛型参数类型将不能作为方法的参数类型,但是可以作为方法的返回值类型。而in刚好相反。协变和逆变类型通配符代替泛型参数,Java中的泛型类型通配符为"?",而Koltin中用"*"来表示类型通配符。
1970-01-01 00:00 · kotlin
[文章] Windows和Mac等上使用VNote做笔记
Developersettings生成的令牌自己记好,直接粘到Vnote的个人访问令牌就会自动保存下来3.1.2Vnote上的操作建好自己的仓库填上(public),存储路径不要写,点击确认就行接下来随便找到一个笔记
2020-08-12 00:42 · 图床 / 笔记
[分享] Android上层应用源代码
在我们学习内容提供者的时候,我们需要去阅读Android上层应用的源码,在我们学习四大组件的时候,想去打开相机呀,设置呀,系统原生应用的时候。我们需要去阅读源码,查看里的意图过滤规则。
2019-10-27 22:04 · 安卓 / 源码 / 应用 / android / app
[文章] 【领券联盟】笔记:视频17-修改TabLayout样式
课堂笔记调整TabLayout和ViewPager的属性<com.google.android.material.tabs.TabLayoutandroid:id="@+id/home_indicator
2020-03-27 02:55 · 学习笔记
[文章] 【领券联盟】笔记:视频20-处理网络错误重新加载动作
BaseFragment的其他子类在重写initView()方法时设置显示成功状态的View@OverrideprotectedvoidinitView(){setUpState(State.SUCCESS);}课堂笔记完善
2020-03-28 03:05 · 课堂笔记
[文章] 【领券联盟】笔记:视频21-把分类数据给到对应页面
课堂笔记ViewPager中的各个HomePagerFragment需要根据id加载显示相应内容,所以我们在新建HomePagerFragment时,需要把Categories.DataBean传入(title
2020-03-29 01:25 · 课堂笔记
[文章] 【领券联盟】笔记:视频19-解决搜索栏非成功情况下不显示
课堂笔记首先创建带顶部Bar和“新坑”的布局base_home_fragment_layoutBaseFragment创建加载rootView的方法protectedViewloadRootView(LayoutInflaterinflater
2020-03-28 02:13 · 课堂笔记
[文章] 笔记二、sqlite数据库
1.创建sqliteOpenHelper类创建表sqlite数据库很简单,拉大锯老师有很详细的视频教程,可以去搜索,一学就会,这里只做简单的笔记
2020-04-25 17:36 · sqlite数据库
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 8