秒懂Kotlin之Java工程师快速掌握Kotlin的技巧

概述

Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。

Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。

在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言。

Kotlin/JVM 可以看做是对改进Java的一种积极的尝试,其试图改进Java编程语言中已知的被广泛讨论的缺点与不足。因为我多年前从事过C#的开发,初次看到Kotlin,感觉好多特性C#好多年前就有了。足见Java是多么的传统,不愿意过多的引入语法糖。

关于Kotlin与Java的爱恨情仇此处按下不表,等有机会单独写一篇相关文章。本文仅想从Java惯用者的角度给出Kotlin与Java的一些不同点,这往往对Java惯用者迅速掌握Kotlin是至关重要的。因为Kotlin是对Java的一种改进,其与Java是100%互操作的,所以Java程序员经过短暂的熟悉后往往可以快速入门,进而熟练掌握Kotlin。

人类学习新事物的一个很重要的方法就是类比,如果新事物与旧事物相似性非常大,那么类比学习的效果会更加明显,从Java到Kotlin非常符合这个特征,以你熟悉的Java来类比不熟悉的Kotlin将会事半功倍,让我们开始吧。

本文基于Kotlin 1.4.0 版本

语法差异

Kotlin与Java在语法上存在一些差异,不算特别巨大,下面列出了我认为最需要适应的几条:

Kotlin中的方法和属性可以不包含在

我们知道,Java中的一切是以class为基础的,都要在class中,但是Kotlin却不是。下面的代码中,方法、属性以及类共存于同一级,同一个文件中都是允许的。

//属性
var name: String = "ShuSheng007"

//方法
fun sum(x: Int, y: Int): Int {
    return x + y
}

//类
class Student{}

Kotlin中语句不需要以;结束

println("hello world")

Kotlin中数据类型是后置的

//变量声明时类型后置
var name: String = "ShuSheng007"

//方法参数及返回值类型后置
fun sum(x: Int, y: Int): Int {
        return x + y
}

Kotlin方法使用fun关键字定义

fun sum(x: Int, y: Int): Int {
        return x + y
}

Kotlin的类和方法默认是public final的

类默认不可以被继承,基类中的方法默认不可以被重写,如果想要被继承或者重写需要用open关键字标记

//Human类可以被继承
open class Human{
	//eat方法可以被overwrite
    open fun eat(){
    }
}

Kotlin中类继承和接口实现使用:标记

//类继承
class Man : Human(){
    override fun eat() {
        super.eat()
    }
}

//实现接口
interface action{
    fun sleep()
}
class Woman :action{
    override fun sleep() {
        //...
    }
}

Kotlin中使用var,val声明变量及属性,而且可以进行类型推断

在Java中,我们声明一个变量必须先指定其类型,例如

String name= "shusheng007";

但是在Kotlin中,编译器可以根据赋值自动推断其类型为String

var name = "shusheng007"

Kotlin存在非空与可空类型

这个也是其宣传的一大亮点,尝试去解决价值几十亿美金的问题:NullPointerException

在Kotlin中每个对象默认都是非null的,除非你显式的将其声明为可null

//非空类型
var name1:String="shusheng"
//可空类型
var name2:String?=null

Kotlin中package可以与文件路径不一致

什么意思呢?假设我们有个类文件在 src/…/top/ss007/learn 文件路径中

那么对于Java 此类的包名必须为

package top.ss007.learn

而对于Kotlin来说就没有这个限制,可以随便叫,例如叫:就是这么任性

package just.so.wayward

确实挺任性的,所以这点建议还是遵守Java的规范更好。

Kotlin中没有受检异常(Checked Exception)

在Java中有很多受检查异常,程序员被强制要求处理它,或者抛给下层调用者处理。但是Kotlin没有这个限制。

Kotlin强调不可变的概念

Kotlin会优先使用不可变对象,例如不可变的集合,不可变的变量。这些不可变对象生成后就只能读取,而不能修改。至于使用不可变对象有很多好处,例如其天然的线程安全性等

以上几条是个人认为的最颠覆我们认知的差异点,熟悉了上面几条后Java程序员就基本上可以看得懂kotlin的代码了

Java中不存在的特性

Kotlin中引入了很多Java中不存在的特性,下面是几条我认为比较重要的

方法类型(Function Type)

在Kotlin中方法是一等公民,意思就是方法就和类一样,类可以干的事,方法都可以干。方法竟然可以作为类型当其他方法的参数传递,当其他方法的返回值类型,当变量的声明类型…这个比较颠覆Java程序员的三观,Java中是没有对应的概念的。如果非要找一个对应物的话,那就是函数接口了。

下面是一个方法类型(两个int 数据 得到一个int,例如1+2=3)。我们完全可以将其看成是java中的一个类,所有可以使用类的地方这家伙都适用,也就是说kotlin中,方法可以当参数传递了,相当于实现了方法引用,牛逼哄哄的。

(Int, Int) -> Int

例如如下方法,第3个参数operation的类型就是上面的方法类型

fun calculate(x: Int, y: Int, operation: (Int, Int) -> Int): Int {
    return operation(x, y)
}
//如何调用
fun sum(x: Int, y: Int): Int {
    return x + y
}
//将sum方法当参数传入了calculate方法中
calculate(4, 5, ::sum)

//我们也可以使用Lambda表达式
calculate(4, 5, { a, b -> a + b })
//当Lambda表达式是方法的最后一个参数时,其可以移到()外面
calculate(4, 5) { a, b -> a + b }

那么如何在Java中实现相同的功能呢?

第一步:按照需求定义一个函数接口

下面的接口只有一个抽象方法,是一个函数接口。

@FunctionalInterface
public interface Fun2<P1, P2, R> {
    R invoke(P1 p1, P2 p2);
}

第二步:将其作为方法参数类型

public int javaCalculate(int x, int y, Fun2<Integer, Integer, Integer> operation) {
     return operation.invoke(x, y);
 }

经过上面两步就搞定了。

当在Kotlin中调用Java中的方法javaCalculate时,IDE会提示如下信息

第一条是告诉你第三个参数可以使用Kotlin中的函数类型,代码如下

javaCalculate(4, 5) { a, b -> a + b }

第二条是比较正统的,告知你需要一个类型为Fun2的参数,代码如下

javaCalculate(4, 5, object : Fun2<Int, Int, Int> {
        override fun invoke(p1: Int, p2: Int): Int {
            return p1 + p2
        }
    })

在Java中我们使用new一个匿名类的对象,而在Kotlin中我们需要使用object关键字

属性(Property)

var name:String="ShuSheng007"

对应Java类里的私有字段(Field)外加getter和setter方法

private String name;

public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

数据类 data class

data class User(val name: String, val age: Int)

大体相当于Java中的JavaBean,但有细微差别,这也是Kotlin大势宣传其简洁性时经常展示的看家特性

密封类 ( Sealed Classes)

这个比较牛逼,Java中没有对应的东东,其主要配合Kotlin中的when使用。最开始见到它的时候我不是很喜欢它,因为它名叫密封类,却可以被继承,后来发现了它设计的精妙性,真的实质性的解决了开发中常常遇到的困境。

  • 其是一种继承受限的类,例如下面的Human类,其具有如下特点
  • 其是abstract类其不可以被直接实例化
  • 其子类必须和其处于同一个文件
sealed class Human {
    abstract fun eat(): Unit
    open fun program(){
        println("I use koltin")
    }
}
class Man : Human() {
    override fun eat() {
    }

    override fun equals(other: Any?): Boolean {
        return this === other
    }

    override fun hashCode(): Int {
        return System.identityHashCode(this)
    }
}

class Woman :Human(){
    override fun eat() {
    }

    override fun program() {
        super.program()
    }
}

那它有什么好处呢?主要就是用在when表达式中,和枚举的功能差不多,但是其可以保护状态,枚举是单例的。

扩展方法(Extension functions)与扩展属性(Extension properties)

这个特性也是kotlin非常重要的特性,有着很广泛的应用。通过扩展方法Kotlin有能力不通过继承而为某个类增加新的方法和属性

例如我们想实现一个wrapWithSymbol, 用于在字符串的前后加上<>,如何实现呢?如果是java的话就只能写一个Utils方法了,而Kotlin可以使用扩展方法来给String类增加一个新方法。

其实现方法如下,注意方法前面的那个要扩展的类型,学名叫receiver

fun String.wrapWithSymbol() :String{
	return "<$this>"
}

//使用
println("my name is ${"shusheng007".wrapWithSymbol()}")

输出:

my name is <shusheng007>

可见已经在目标字符串前后加上了<>,从调用方式来看,wrapWithSymbol方法就像是String类的方法一样。

扩展属性与扩展方法类似:

val <T> List<T>.lastIndex: Int
    get() = size - 1

//调用
println(listOf(1,2,3,4).lastIndex)

操作符重载

这个其实还是比较复杂的,也容易被滥用,我认为应该属于进阶知识,此处仅简单的简绍一下。

Java是不支持操作符重载的,其实有没有它也不影响大局。

那什么是操作符重载呢?想要理解这个问题,首先必须理解什么是操作符?

例如我们编程时候经常用到 a++, a--, a+b, a==b ,a in b等等,其中那些++,--,+,== ,in就是操作符。

那什么是重载呢?这些操作符本身都是有自己的含义的,但是我们通过重载方式可以改变这些操作符的含义,这个过程就叫操作符重载。

在kotlin中,可以重载的操作符集合及其对应的方法都是预先定义好的,不能随便重载。下面列出其中的一组:

Expression Translated to
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.rem(b), a.mod(b) (deprecated)
a…b a.rangeTo(b)

操作符重载的方法既可以是实例方法,也可以是扩展方法。

我们尝试使用实例方法重载一下上表中的+操作符。有两点需要注意:

  1. 重载方法必须以operator 标记
  2. 重载方法名称和参数必须是Kotlin预先定义好的,例如此处的 plus
data class Point(val x: Int, val y: Int){
	operator fun plus(p: Point): Point {
        return Point(p.x + x,p.y + y)
    }
}

//调用
 val p1 = Point(1, 2)
 val p2 = Point(3, 4)
 println(p1 + p2)

输出:

Point(x=4, y=6)

可见,通过重载+操作符,我们改变了其内在的含义,使得+也能用于对象了。

协程

较复杂,需要单独文章描述

到此这篇关于秒懂Kotlin之Java工程师快速掌握Kotlin的技巧的文章就介绍到这了,更多相关Kotlin开始入门内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android动画入门教程之kotlin

    前言 Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿Android的人,我们必须尽快了解和使用Kotlin语言. 本文将详细介绍Android动画入门之kotlin的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 属性动画 简述 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(frame-by-frame animatio

  • Kotlin 编程三分钟入门

    为什么使用Kotlin 项目一期在收尾了终于有时间折腾了,一个多月以来Kotlin从入门到现在,坚持用来开发的切身感受.因为语法与Java的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人会尝试这样一门小众语言,但是习惯后会发现这些年究竟浪费多少时间在写无用的Java代码了,Kotlin在兼容Java的基础上还能大大提升开发效率.Kotlin有许多特性但对于开发来说,快速适应和学习更为重要,很多时候我们都是在不明白其原因就开始使用的,正如我们不可能把Retrofit原理研究透才使用它

  • Android 官推 kotlin-first 的图片加载库——Coil的使用入门

    Coil 是一个非常年轻的图片加载库,在 2020 年 10 月 22 日才发布了 1.0.0 版本,但却受到了 Android 官方的推广,在 Android Developers Backstage 这个博客中专门聊过一期.推广的原因比较简单:一方面是这个库确实做得很好,另一方面是这个库完全是用 Kotlin 写的,而且运用了大量 Kotlin 的特性,尤其是协程.所以 Google 嘴上说着不会放弃 Java,但实际上咱们都懂的. Coil 名字的由来:取 Coroutine Image

  • Room Kotlin API的使用入门教程

    Room 是 SQLite 的封装,它使 Android 对数据库的操作变得非常简单,也是迄今为止我最喜欢的 Jetpack 库.在本文中我会告诉大家如何使用并且测试 Room Kotlin API,同时在介绍过程中,我也会为大家分享其工作原理. 我们将基于 Room with a view codelab 为大家讲解.这里我们会创建一个存储在数据库的词汇表,然后将它们显示到屏幕上,同时用户还可以向列表中添加单词. 定义数据库表 在我们的数据库中仅有一个表,就是保存词汇的表.Word 类代表表中

  • spring boot + jpa + kotlin入门实例详解

    spring boot +jpa的文章网络上已经有不少,这里主要补充一下用kotlin来做. kotlin里面的data class来创建entity可以帮助我们减少不少的代码,比如现在这个User的Entity,这是Java版本的: @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; private String firstName; private S

  • Kotlin入门教程之开发环境搭建

    前言 众所周知,随着Google I/O大会的召开,Google宣布将支持Kotlin作为Android的开发语言,最近几日,关于Kotlin的文章.介绍就异常的活跃.工欲善其事,必先利其器,所以今天就为大家介绍一下如何搭建kotlin的开发换环境,话不多说了,来一起看看详细的介绍吧. 需要注意的是:这里的环境搭建并不会局限于Android的环境. Kotlin简介 在开始搭建环境之前,先来简单的看一下Kotlin.官方网址https://kotlinlang.org/ Kotlin 是一个基于

  • 秒懂Kotlin之Java工程师快速掌握Kotlin的技巧

    概述 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源. Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行. 在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言. Kotlin/JVM 可以看做是对改进Java的一种积极的尝试,其试图改进Java编程语言中已知的被广泛讨论的缺点与不足.

  • 利用Kotlin Tools如何快速添加Kotlin依赖详解

    前言 2017 Google IO 大会,宣布将支持Kotlin作为开发语言.自此Kotlin成为了Android开发中的又一官方支持语言,当然这并不表明Google 已经放弃了对Java 语言的支持.总体上来说,因为Kotlin是一门JVM语言,所以从本质上来讲,Kotlin 和 Java 没什么区别. Kotlin是一种在JAVA虚拟机上可以运行的静态类型编程语言,也可以被编译为JavaScript源码,它被设计为可以与JAVA代码相互运作,甚至可以使用大量的现有JAVA类库,得益于这个性质

  • Kotlin与Java的区别详解

    什么是Kotlin? Kotlin是一种可以在 Java 虚拟机 (JVM) 上运行的开源编程语言.该语言可以在许多平台上运行. 它是一种将面向对象编程 (OOP) 和函数式编程结合在一个不受限制.自给自足且与众不同的平台中的语言. 什么是Java? Java 是一种多平台.面向对象.以网络为中心的编程语言.它是最常用的编程语言之一.它也用作计算平台,最早由 Sun Microsystem 于 1995 年发布,后来被 Oracle 公司收购. 主要区别: Kotlin 结合了面向对象和函数式编

  • Kotlin 与 Java基本语法对比

    Kotlin 与 Java基本语法对比 Kotlin比Java更年轻,但它是一个非常有前途的编程语言,它的社区不断增长. 每个人都在谈论它,并说它很酷. 但为什么这么特别? 我们准备了一系列文章,分享我们在Kotlin开发Android应用程序的经验. 我们将讨论Kotlin与Java在语法,可用性,UI性能和异步性方面的区别,以便您可以决定哪种语言最适合您. 让我们从一些基本的语法差异开始. 这是第一个: 1. 使用Kotlin,你可以用更少的代码做更多 Kotlin的一个主要优点是它的简洁.

  • Kotlin与Java的主客观对比分析

    Kotlin Kotlin是一门相对比较新的JVM语言,JetBrains自2011年以来一直在积极地开发. 多年来,该语言在Android社区受到的关注度越来越高,并在Google IO 2017大会之后成为Android开发领域最热门的话题.这次大会宣布,Android正式支持Kotlin. 遗憾的是,虽然已经有许多关于Kotlin的文章,但并没有多少客观信息,许多开发人员仍然在苦思冥想,迁移到Kotlin是否是一条正确的道路. 在本文的剩余部分,我将尝试提供一个在将Kotlin作为Java

  • kotlin和Java的相互调用示例详解

    前言 互操作就是在Kotlin中可以调用其他编程语言的接口,只要它们开放了接口,Kotlin就可以调用其成员属性和成员方法,这是其他编程语言所无法比拟的.同时,在进行Java编程时也可以调用Kotlin中的API接口. 1.在kotlin中调用Java方法 Kotlin和Java是两种不同的语言,所以在互相调用的时候,会有一些特殊的语法.kotlin中对象属性默认就带有setter和getter方法,所以在kotlin中调用Java时直接变量名点属性就可获取到属性的setter和getter的一

  • Kotlin 和 Java 混合开发入门教程

    目录 一.前沿 二.学习 Kotlin 前准备 三.Kotlin 语法简介 优秀的表达式 加强版 switch 模板字符串 空指针异常不存在了 编写单例类 扩展方法 运算符重载 四.Kotlin 与 Java 混合开发 五.Kotlin 与 Java 总结 一.前沿 如果你学习过其他的编程语言,你就会发现 Java 的语法很是哆嗦,可是我们为什么没有放弃 Java 这门编程语言呢?因为 JVM 是一个非常好的平台,而且 Java 程序员目前在中国所占的比重实在是太高了.这是历史包袱导致的.暂且不

  • kotlin改善java代码实例分析

    序 本文主要举几个kotlin如何改善java代码的例子 字符串字面值及模板 字符串字面值 @Test fun testStringLiterals(){ val a = """if(a > 1) { | return a |}""".trimMargin() println(a) val b = """Foo Bar""".trimIndent() println(b) } 有了

  • 详解分别用Kotlin和java写RecyclerView的示例

    本文介绍了分别用Kotlin和java写RecyclerView的示例,分享给大家,具体如下: java:跟一般的写法一样,增加了按钮响应 MainActivity: public class MainActivity extends AppCompatActivity implements RecyclerAdapter.OnItemClickListener{ private RecyclerView mRecyclerView; private RecyclerView.LayoutMan

  • Kotlin与Java相互调用的完整实例

    目录 一.Kotlin 调用 Java 二.Java 调用 Kotlin 附 Github 源码: 总结 一.Kotlin 调用 Java 1. kotlin 关键字转义 java 中的方法或变量 是 kotlin 的关键字时,使用反引号 `` 对关键字进行转义 // java public class JavaDemo { String is; public String getIs() { return is; } public void setIs(String is) { this.is

随机推荐