Kotlin关键字三——fun与方法

前两节笔记分析了属性的定义构造方法,这次看下修饰方法的关键字fun。

基本使用

fun应该说是kotlin所有关键字中最简单的一个,比var都简单,就是用在方法名前标识这是个方法。kotlin中方法定义的基本结构是:

kotlin 复制代码
访问修饰符 fun 方法名(参数名一:类型一, 参数名二:类型二,...):返回类型{
	...
    return 返回值
}

格式很简单,但还是需要注意几点

  • 默认的访问修饰符是public
  • 方法默认是final的,不能被子类重写
  • 无返回值时返回类型可以不写,与java不同的是不写返回类型时kotlin返回的Unit而不是void

按上面的模版为Person添加方法:

kotlin 复制代码
class Person(var name: String, var age: Int) {
    fun introduce(description: String): String {
        return "我叫${name},我今年${age}岁,${description}"
    }
}

// 调用
val person = Person("张三",28)
val introduce = person.introduce("我对这份工作非常感兴趣")
// 会输出: 我叫张三,我今年28岁,我对这份工作非常感兴趣
println(introduce)

默认参数

在上面introduce方法中,如果参数description大多时候都是相同的,那么就可以使用默认参数来定义方法:

kotlin 复制代码
class Person(var name: String, var age: Int) {
    fun introduce(description: String = "我对这份工作非常感兴趣"): String {
        return "我叫${name},我今年${age}岁,${description}"
    }
}

// 调用
val person = Person("张三",28)
val introduce = person.introduce()
// 同样会输出: 我叫张三,我今年28岁,我对这份工作非常感兴趣
println(introduce)

通过设置默认值在一定程度上方便了我们的调用。而在java中可以通过方法重载实现该功能。而java中方法重载需要我们写两个方法,而kotlin中的默认参数只需要写一个方法。

实现原理

转换成java代码如下:

java 复制代码
public final class Person {
    public final String introduce(@NotNull String description) {
      return "我叫" + this.name + ",我今年" + this.age + "岁," + description;
   }

   public static String introduce$default(Person var0, String var1, int var2, Object var3) {
      if ((var2 & 1) != 0) {
         var1 = "我对这份工作非常感兴趣";
      }
      return var0.introduce(var1);
   }
}

public final void main() {
   Person person = new Person("张三", 18);
   Person.introduce$default(person, (String)null, 1, (Object)null);
}

可以看到会多生成一个静态方法Person.introduce$default , main方法中调用的实际上也是这个静态方法。

这个静态方法中一共有4个参数

参数名 作用
var0 对象的具体实例
var1 对应introduce放在中的description参数
var2 &1来判断是否传入了description的值
var3 方法中没有使用,不知道它的作用,有知道的小伙伴可以在留意,感谢!!!

推测下,如果再定义一个默认参数,Person.introduce$default会不会再多出两个参数,一个用来标识这个参数是否有值,一个用了传值?验证下:

kotlin 复制代码
fun introduce(description: String = "我对这份工作非常感兴趣", salary: Int = 50000): String {
        return "我叫${name},我今年${age}岁,${description}, 我的期望薪资是${salary}"
}

对于有多个默认参数的方法,可以在调用是直接通过参数名来指定为哪个参数复制:

kotlin 复制代码
// 可以在调用是直接指明为哪个参数赋值
person.introduce(salary = 30000)

对应的java代码

java 复制代码
public static String introduce$default(Person var0, String var1, int var2, int var3, Object var4) {
  if ((var3 & 1) != 0) {
       var1 = "我对这份工作非常感兴趣";
    }

    if ((var3 & 2) != 0) {
       var2 = 50000;
    }
    return var0.introduce(var1, var2);
}

可以看到与之前相比只增加了一个参数,分别用&1和&2来标识第一默认参数和第二个默认参数是否有值

看到有朋友这么描述此时的var3:与有默认参数在静态方法参数的index做&操作,不等于表示参数没有传值,使用默认参数。如果为0表示有传值直接调用实例的具体方法实现。 这个说法是错误的,&的并不是索引,而是二进制的位数对应的值。

用一个int类型变量,它的二进制数从低到高依次对应每一个默认参数,0代表无值,1代表有值

疑问?int是32位的,如果默认参数超过32个会怎么样,感兴趣的小伙伴可以试下。

相关推荐
是程序喵呀几秒前
MySQL备份
android·mysql·adb
casual_clover2 分钟前
Android 之 List 简述
android·list
锋风Fengfeng1 小时前
安卓15预置第三方apk时签名报错问题解决
android
User_undefined2 小时前
uniapp Native.js原生arr插件服务发送广播到uniapp页面中
android·javascript·uni-app
程序员厉飞雨3 小时前
Android R8 耗时优化
android·java·前端
小白学大数据4 小时前
高级技术文章:使用 Kotlin 和 Unirest 构建高效的 Facebook 图像爬虫
爬虫·数据分析·kotlin
丘狸尾4 小时前
[cisco 模拟器] ftp服务器配置
android·运维·服务器
van叶~6 小时前
探索未来编程:仓颉语言的优雅设计与无限可能
android·java·数据库·仓颉
Crossoads10 小时前
【汇编语言】端口 —— 「从端口到时间:一文了解CMOS RAM与汇编指令的交汇」
android·java·汇编·深度学习·网络协议·机器学习·汇编语言
li_liuliu11 小时前
Android4.4 在系统中添加自己的System Service
android