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

相关推荐
踏雪羽翼12 小时前
android TextView实现文字字符不同方向显示
android·自定义view·textview方向·文字方向·textview文字显示方向·文字旋转·textview文字旋转
lxysbly13 小时前
安卓玩MRP冒泡游戏:模拟器下载与使用方法
android·游戏
夏沫琅琊15 小时前
Android 各类日志全面解析(含特点、分析方法、实战案例)
android
程序员JerrySUN15 小时前
OP-TEE + YOLOv8:从“加密权重”到“内存中解密并推理”的完整实战记录
android·java·开发语言·redis·yolo·架构
TeleostNaCl17 小时前
Android | 启用 TextView 跑马灯效果的方法
android·经验分享·android runtime
TheNextByte117 小时前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn18 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪19 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥20 小时前
Android分层
android
极客小云21 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试