一:常见语法糖【https://www.runoob.com/kotlin/kotlin-tutorial.html】
1.【安卓】import android.R
R.id.myTextView1是指向布局中的空间TextView,
这个Textview的id被设置成了"@+id/myTextView1",你到layout文件夹下找main.layout就能看到它。
并且不使用import android.R 若果使用的话R.id就会去R包下面去找,报错
import java.util.TreeMap
fun main(args: Array<String>) {
var a="zero"
val b:Long=1231
//类型转换
var l=12
var m="12"
l=m.toInt()
m=l.toString()
println(a)
println(b)
sayHello()
println(diary("panada"))
println(getmess(null))
var nums=1..10//声明数组区间
for(num in nums)
print(num)
//list 的引用
var lists= listOf("1","2",3)
// for(list in lists)
// print(list)
//有序列
for((i,e)in lists.withIndex()) {
println("$i $e")
}
//map运用 类似词典 且有索引
var map=TreeMap<String,String>()
map["好"]="good"
map["学"]="study"
map["向上"]="up"
println(map["好"])
print(z(3,5))
//ps调用float单精度area(3.0f,3.0f)
}
//函数
fun sayHello(){
println("Hello")
}
//无参数无返回类型
//fun sum(a: Int, b: Int): Int=x+y
fun sum(a: Int, b: Int): Int { // Int 参数,返回值 Int
return a + b
}
var z={x:Int,y:Int -> x+y}
var y:(Int,Int)->Int={x,y ->x+y}
//print包裹dollar参数取值
fun diary(place:String):String{
var message="你好${place}"
return message
}
//排除空指针异常+?表示传入可为“null”
fun getmess(mess:String?):String{
return "得到"+mess
}
//switch与when语句
fun grade(score:Int){
when(score){
10-> print("考了满分")
8-> print("考的不错")
else-> print("继续加油")
}
}
2.5数组在 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>
// ……
}
为了获得更好的效率,Kotlin提供了原生类型数组:ByteArray
、 ShortArray
、IntArray
等,不需要装箱开销,它们和Array没有继承关系,但又同样的方法属性,也有相应的工厂方法。
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
// 大小为 5、值为 [0, 0, 0, 0, 0] 的整型数组
val arr = IntArray(5)
// 例如:用常量初始化数组中的值
// 大小为 5、值为 [42, 42, 42, 42, 42] 的整型数组
val arr = IntArray(5) { 42 }
int max=(a>b)?a:b;
if不只是条件语句,它还是表达式,因此Kotlin没有c的三元运算符,它可以用if表达式取代:
val max = if (a > b) a else b
二:输入输出
fun main(args: Array<String>){
while (true){
println("请输入第一个数字")
var num1= readLine()
println("请输入第二个数字")
var num2= readLine()
//35字符串连接
/* var num3=num1?.toInt()
var num4=num1?.toInt()
println("${num3}+${num4}=${num3+num4}")*/
//?输入为空则空,但空和空无法相加会报错 !!抛出空指针异常
//更新输入a抛出异常,结合while就可以一直运行,不报运行代码错误
try {
var num3:Int=num1!!.toInt()
var num4:Int=num2!!.toInt()
println("${num3}+${num4}=${num3+num4}")
}catch (e:Exception){
println("大哥,你输入的有问题吧 ")
}
}
}
三.方法与调用
class Girl(var chactor:String,var voice:String){//静态构造
//两个动态方法
fun smile(){
println("妹子笑了一下,么么哒")
}
fun cry(){
println("呜呜呜,人家伤心")
}
}
fun main(args: Array<String>){
var girl1=Girl(chactor = "温柔",voice = "甜美")
print("girl1这位妹子的声音:${girl1.voice}")
girl1.cry()
girl1.smile()
}
import javax.swing.tree.FixedHeightLayoutCache
//矩形类与复合类型
class Rect(var height:Int,var width:Int)
fun main(args: Array<String>){
var rect1=Rect(height = 10,width = 20)
print("矩形的高度:${rect1.height}")
}
ps:用when替代switch
一.起因//主构造函数的属性可以会成为内部类的属性
- Kotlin类的构造函数名是constructor(符合一定条件,主构造函数名可以省略),而不是类名
- Kotlin类的主构造函数的参数自动成为类的成员属性
- Kotlin没有static关键字,因此不存在静态成员,伴生对象成员可以起到静态成员的作用
用这种构造方法报错了:supertype initiallzation is impossible without primary constructor
class LocalMusicAdapter: RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {
//传入数据源
var context: Context?=null
var mDatas: List<LocalMusicBean>? = null
//创建构造方法
constructor(context: Context?, mDatas: List<LocalMusicBean>?) {
this.context = context
this.mDatas = mDatas
}
// fun LocalMusicAdapter(context: Context, mDatas: List<LocalMusicBean>) {
// this.context = context
// this.mDatas = mDatas
// }
默认情况下:主构造函数可以是无参构造函数
和次级构造函数的区别标志在于他写在类名后面
拓展:有主构造函数和无的区别
关于无参构造函数:
创建一个子类对象的实例的时候,必先调用父类的无参构造函数(默认构造函数),假如父类有带参数的构造函数,那么系统不会给他创建无参数的构造函数,这时,子类在实例化的时候,因为找不到父类的默认构造函数,编译器会报错,如果在子类的构造函数中指定使用父类的带参数的构造函数的时候,或者在父类中加一个无参数的构造函数的时候,就不会报错了。
二.文档
//没有static静态成员-》伴生对象
//原生数组与Array泛型取代数组
三.关于kotlin与空指针异常【https://www.jianshu.com/p/51b2e5aa3dd8】
这是因为编译器在转化时为了保证代码转化前后的一致性所造成的。换句话说,在Java上出异常的,转化到KT上,编译器任然会让他保持抛出异常,NullPointerException也是如此。
所以结合上下文可以看得出,!!加上去后好像并没有和之前Java代码有什么区别嘛,该null的地方任然会抛出异常。所以大多数情况下都会使用?来检测null,轮不到!!出场。!!只会在你需要对某对象进行非空判断,并且需要抛出异常时才会使用到。
即翻译时的逻辑一制性。
类型转换,如果不成功可能会导致 ClassCastException
可以使用as?操作符,不成功则返回null
val aInt: Int? = a as? Int
选择->音乐->额外存储
四.构造器,主构造方法,次级构造方法
//典型画蛇添足样例
五.错误实例【java型kotlin编码】
package com.ywjh.localfaraway
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import android.view.View
import android.widget.TextView
import android.view.LayoutInflater
class LocalMusicAdapter(): RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {
//传入数据源
var context: Context?=null
var mDatas: MutableList<LocalMusicBean>? = null
//创建构造方法
constructor(context: Context?, mDatas: MutableList<LocalMusicBean>?) : this() {
this.context = context
this.mDatas = mDatas
}
// fun LocalMusicAdapter(context: Context, mDatas: List<LocalMusicBean>) {
// this.context = context
// this.mDatas = mDatas
// }
//创建并返回 ViewHolder 生成与初始化
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalMusicViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_local_music, parent, false)
val holder = LocalMusicViewHolder(view)
return holder
}
//返回条目数量
override fun getItemCount(): Int {
return mDatas!!.size
}
//绑定Viewholder 拿到holser后对TextView进行设置
override fun onBindViewHolder(holder: LocalMusicViewHolder, position: Int) {
val musicBean = mDatas?.get(position)
holder.idTv?.setText(musicBean!!.getId())
holder.songTv?.setText(musicBean!!.getSong())
holder.singerTv?.setText(musicBean!!.getSinger())
holder.albumTv?.setText(musicBean!!.getAlbum())
holder.timeTv?.setText(musicBean!!.getDuration())
//holder.itemView.setOnClickListener { v -> onItemClickListener.OnItemClick(v, position) }
}
class LocalMusicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
//继承recycleView和ViewHolder内部类
var idTv: TextView? = null
var songTv:TextView? = null
var singerTv:TextView? = null
var albumTv:TextView? = null
var timeTv:TextView? = null
public fun LocalMusicViewHolder(itemView: View) {//kotlin 当中没有这种构造方法,所有不会进行初始化
idTv = itemView.findViewById(R.id.item_local_music_num)
songTv = itemView.findViewById(R.id.item_local_music_song)
singerTv = itemView.findViewById(R.id.item_local_music_singer)
albumTv = itemView.findViewById(R.id.item_local_music_album)
timeTv = itemView.findViewById(R.id.item_local_music_durtion)
}
}
}
更改后
1.原本理解不够,写的特别有问题,【LocalMusicAdapter】kotlin的主构造方法传入两个参数,var一下之后 内部就可以直接用【就相当于构造方法初始化过了】
2.【 LocalMusicViewHolder】有主构造方法传个View,接着使用init方法自动初始化就好了
3.借鉴了这位大佬的帖子,里面还有伴生对象的说明【https://blog.csdn.net/yuzhiqiang_1993/article/details/87863589】
package com.ywjh.localfaraway
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.ywjh.localfaraway.LocalMusicBean
class LocalMusicAdapter(internal var context: Context, internal var mDatas: List<LocalMusicBean>) :
RecyclerView.Adapter<LocalMusicAdapter.LocalMusicViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LocalMusicViewHolder {
val view = LayoutInflater.from(context).inflate(R.layout.item_local_music, parent, false)
//ps val holder = LocalMusicViewHolder(view)
// return holder
return LocalMusicViewHolder(view)
}
override fun onBindViewHolder(holder: LocalMusicViewHolder, position: Int) {
val musicBean = mDatas[position]
holder.idTv.setText(musicBean.getId())
holder.songTv.setText(musicBean.getSong())
holder.singerTv.setText(musicBean.getSinger())
holder.albumTv.setText(musicBean.getAlbum())
holder.timeTv.setText(musicBean.getDuration())
}
override fun getItemCount(): Int {
return mDatas.size
}
inner class LocalMusicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var idTv: TextView
var songTv: TextView
var singerTv: TextView
var albumTv: TextView
var timeTv: TextView
init {
idTv = itemView.findViewById(R.id.item_local_music_num)
songTv = itemView.findViewById(R.id.item_local_music_song)
singerTv = itemView.findViewById(R.id.item_local_music_singer)
albumTv = itemView.findViewById(R.id.item_local_music_album)
timeTv = itemView.findViewById(R.id.item_local_music_durtion)
}
}
}
六.惰性加载
在使用kotlin
开发中,因为各种原因,我们会经常需要使用到延迟加载的功能,目前kotlin
的延迟加载主要有两种:lateinit
和lazy
在var
之前添加lateinit val使用lazy【
https://blog.csdn.net/liyi1009365545/article/details/84236433】
七.伴生对象
在Java中可以通过static关键字声明静态的属性或方法。但是在Kotlin中并没有延用这个关键字,而是使用伴生对象实现,在class内部声明一个companion object代码块,其内部的成员变量和方法都将被编译成为静态的。【https://www.jianshu.com/p/ac0c25091491】
其与匿名内部类的区别(companion object代码块中的成员变量最终会被声明到外部类中,也这是为什么我们能通过外部类名直接访问,而object类则需要用外部类.内部类的方式调用。)
八.接口
java中若接口的方法只有一个,可以直接省去实现接口参数,直接复写方法就好了