Kotlin(4) java转kotlin潜规则,Android开发6年了

fun main(){
Test001.s
Test001.t1()
}


注:每一个kotlin类中,只能有一个共生体对象. 

但是在java调用kt的"静态"成员方法时,必须带上共生体,但是,访问"静态"成员变量,则不能带:

```Java
public static void main(String[] args) {
        Test001.Companion.t1();//Java访问kt的t1()共生体方法,必须带上Companion
        String s2 = Test001.s;// 而访问共生体成员变量,不能带Companion
 }

好纠结。为什么要这么设计。算了。查了一下kt反编译之后的Java源码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBUpXlzT-1630670636954)(Kotlin(4)] java转kotlin潜规则.assets/image-20200103164440541.png)

共生体变成了Java类中的静态内部类,包含t1()方法。而s,s2 则是普通的静态变量。


修饰符

修饰符指的是 类 和 成员变量,成员方法 前面的 权限访问关键字。原 Java拥有 private ,protected,default ,public ,访问权限分别为: 本类内部,同包名或子类,同包名,全局。

然而,kotlin新增了一个概念,internal ,表示,相同Module内可访问,跨Module则不行。

并且,java和kotlin的 private ,protected,default ,public 的访问权限还有区别,但是我这里就不详述了,因为我觉得意义不大。能不能访问,写代码的时候编译器会告诉你,当场警告你,你就会修改代码。如果有问题。可以把kotlin Decompile成Java代码自己去对比试试。如有需要,后期再说吧。


空指针问题

通常要快速的将 旧java代码转化成kotlin代码,是拷贝java代码粘贴到kotlin文件内,让as自动转化,但是这种方式,容易造成很多空指针问题,有一些是很直白的报了编译错误,而有一些则是隐藏起来,等到程序运行时才会报错。直接报错的就不提了,下面演示隐藏的空指针问题:

Kotlin类:

class Student(name:String) {
    var name: String = name

    fun showName(tag: String) {
        println("$tag : $name")
    }
}

Java调用kt:

public class Main {
    public static void main(String[] args) {
        Student s = new Student("zhou");
        s.showName(null);
    }
}

此时,如果运行main函数,就会报出:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IoCtTrU1-1630670636956)(Kotlin(4)] java转kotlin潜规则.assets/image-20200103165613561.png)

告诉我们参数tag不可为null。但是奇怪的是,在java代码中,居然不会报编译错误。贼特么诡异。

解决方案:

在方法参数后面加上问号,变成这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JTMStzLA-1630670636958)(Kotlin(4)] java转kotlin潜规则.assets/image-20200103165838953.png)


没有基本数据类型

Kotlin之中没有基本数据类型,它只有:
Int,Short,Long,Float,Double,Byte ,Char,Boolean 这样的包装类型。
为什么没有?没有必要去纠结,但是只提供包装类型有一个好处,那就是 方便扩展函数的定义。
我们可以很轻松地对 Int,类型去扩展函数。
比如: Kotlin自带了很多扩展函数:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMb4S8rl-1630670636960)(Kotlin(4)] java转kotlin潜规则.assets/image-20200103152004966.png)

这是系统定的,我们也可以自己来定义:

fun Int.plus100(): Int {//自定义扩展
    return this + 100
}
fun main() {
    val a: Int = 20
    println("${a.plus100()}")
}

继承

在用kt重构部分模块的过程中,我发现频繁出现下面的问题:

Kotlin基类:

abstract class Person(name: String) {
    var name: String? = name
}

Java子类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LBGZjeTr-1630670636961)(Kotlin(4)] java转kotlin潜规则.assets/image-20200103154351222.png)

由于我是从基础类开始重构,所以,在原先的Java代码中频繁出现了类似这种 访问权限不足的问题。一个一个去改成setName函数,工作量巨大。后来找到一个办法:

在kotin中加入 @JvmField 变成这样:

abstract class Person(name: String) {
    @JvmField
    var name: String? = name
}

@JvmField可以让 kotlin的成员属性变成公有的,kt转化成java时,会是如下这样:

public abstract class Person {
   @JvmField
   @Nullable
   public String name;

   public Person(@NotNull String name) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
   }
}

兼容原先的Java代码。不用大面积修改了。


默认支持可选命名参数

了解高级语言语法的同学肯定知道 可选命名参数可选位置参数,经测试: Kotlin的任何方法(包括构造方法和普通和方法),可以这么写:

fun test001(s: String, s1: String) {
    println("$s -  $s1")
}

fun main() {
    test001(s = "1111", s1 = "2222") //卧槽,Kotlin默认支持 可选命名参数
}

这种特性可以很好的避免了Java中出现的一个方法包含N个参数 把人眼睛看花的情况:

private void test(String s1, String s2, String s3, String s5, String s6, String s7, String s8, String s9, String s10, String s11, String s12) {
        //...
    }

比如如上面所示,一个方法,有12个String参数,看多了会骂娘,谁特么写的。然而,用kotlin:

fun test(s1: String, s2: String, s3: String, s4: String, s5: String, s6: String, s7: String, s8: String, s9: String, s10: String, s11: String, s12: String) {}
fun main() {
    test(s1 = "",s2 = "",s3 = "",s4 = "",s5 = "",s6 = "",s7 = "",s8 = "",s9 = "",s10 = "",s11 = "",s12 = "")
}

直觉上这种语法,融入了 建造者设计模式。让同一个函数的多个参数不再混乱。当然如果你怀旧的话,你也可以用原始方法,12个string依次摆下去。反正我不会这么做。


类,成员方法 默认封闭

和Java相反,kotlin给类,成员方法 都采用了默认封闭原则。具体体现为:类,默认不可继承,成员方法默认不可重写(继承时)。如果要继承类,或者重写父类方法,必须在父类中手动加入 open 关键字,子类中重写方法必须加上override关键字 :

kotlin父类:

open class Student(name:String) {
    var name: String = name

    open fun showName(tag: String?) {
        println("$tag : $name")
    }
}

kotlin子类:

class StudentExt(name: String) : Student(name) {
    override fun showName(tag: String?) {
        super.showName(tag)
        println("xxxxx")
    }
}

Kotlin中方法和函数的区别

函数,是c/c++的词汇,而方法,则是Java里面。现在kotlin中同时存在了方法和函数,那么区别在哪里?

通常我们人为:在Kotlin类内部,称为成员方法。而在类外部定义的,则成为全局函数(这里就不用去讨论kotlin变成java之后长什么样)。

应用到具体场景,一句话解释清楚:

A.kt 中有一个A类,它有a()成员方法。 同时我们可以在 B.kt中给A类扩展一个函数。创建一个A类对象之后,我们既可以调用a()成员方法,又可以调用它的扩展函数。

A.kt

class A {
    fun a() {}
}

B.kt

## 写在最后

本次我的分享也接近尾声了,感谢你们在百忙中花上一下午来这里聆听我的宣讲,希望在接下来的日子,我们共同成长,一起进步!!!

最后放上一个大概的Android学习方向及思路(详细的内容太多了~),提供给大家:

![](https://img-blog.csdnimg.cn/img_convert/d8414a16807d8f26c3f4f2fb2045d9f7.png)

对于程序员来说,要学习的知识内容、技术有太多太多,这里就先放上一部分,其他的内容有机会在后面的文章向大家呈现出来,不过我自己所有的学习资料都整理成了一个文档,一直在不断学习,如今整理的资料不知不觉居然已经有将近**80G**了,希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

> **[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://codechina.csdn.net/m0_60958482/android_p7)**

**为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!**

Android架构师之路很漫长,一起共勉吧!

如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

厂面试真题+项目实战源码》](https://codechina.csdn.net/m0_60958482/android_p7)**

**为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!**

Android架构师之路很漫长,一起共勉吧!

如果你觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

![](https://img-blog.csdnimg.cn/img_convert/a31a42fc7b75be02ac7b8dd558cdd4ae.png)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值