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个会怎么样,感兴趣的小伙伴可以试下。

相关推荐
修炼者2 小时前
bitmap和drawable的互相转换
android
美狐美颜SDK开放平台2 小时前
美颜SDK接入流程详解:Android、iOS、鸿蒙兼容方案解析
android·人工智能·ios·华为·harmonyos·美颜sdk·视频美颜sdk
笔夏4 小时前
【安卓学习之FloatingActionButton】按钮太小
android·学习
XD7429716364 小时前
科技早报晚报|2026年5月15日:无摄像头空间感知、Android 设备实验室与视频检索代理,今天更值得跟进的 3 个技术机会
android·科技·音视频·开源项目·边缘ai·开发者工具
应用市场4 小时前
Android Verified Boot 2.0 安全启动原理详解
android·安全
只可远观5 小时前
Android XML命令式和Jetpack Compose声明式UI
android·xml
他是龙5515 小时前
DVWA 靶场深度解析:文件包含 & 文件上传(Low → Impossible)
android
_李小白5 小时前
【Android车载学习笔记】第一天:Android Automotive OS介绍
android·笔记
aqi005 小时前
FFmpeg开发笔记(一百零一)跨平台的开源音视频移动框架MobileFFmpeg
android·ffmpeg·音视频·直播·流媒体