类与对象
获取类的class
val kClass: KClass<Any> = Any::class
val clazz: Class<Any> = Any::class.java
在 Kotlin 中,::class
和 ::class.java
返回的类型和用途有所不同。前者用于 Java 的反射和与 Java 代码交互,后者用于 Kotlin 的类型检查和反射。
KClass
是 Kotlin 提供的运行时类型信息的类,它提供了很多关于类本身的信息,比如类名、父类、成员函数等。KClass
是类型安全的,并且只能用于 Kotlin 代码中。
class
是 Java 的运行时类型信息表示。Class
对象提供了 Java 反射 API 的入口,允许你在运行时查询和操作类的各种信息。这个对象通常用于与 Java 框架或库交互,或者当你需要使用 Java 的反射功能时。
静态属性
在kotlin中,如果想要在类中定义静态变量,有两种方法(不算单例类):
- 顶层级变量:在该类文件中类的外部定义变量
- 伴生对象变量:使用
companion object
关键字在类内部定义伴生对象,可以使用@JvmStatic
注解简化操作。
对象表达式
在Kotlin中,对象表达式允许你在不定义类的情况下创建一个对象的实例。对象表达式在语法上类似于一个匿名内部类,但更简洁。
interface MyInterface {
fun doSomething()
}
fun main() {
val myObject: MyInterface = object : MyInterface {
override fun doSomething() {
println("Doing something...")
}
}
myObject.doSomething() // 输出 "Doing something..."
}
静态内部类
定义静态内部类时,不需要要加inner
关键字。但此时内部类就无法持有外部类的引用的(无法this@外部类目
),因为它相当于一个独立的类,不是作为实例属性。
私有set方法
私有化set
class User {
var username: String? = null
private set
}
返回null类型
java中的void对应kotlin中的Unit,java的null则对应kotlin中的 Nothing
注解
数组属性
kotlin中注解属性为数组的,表示形式从{}
变成[]
了,并且Class
类型的属性用KClass
替代了。
常用函数
use函数
java7引入的try-with-resources语法糖可以自动关闭流对象,在kotlin中可以用use方法达到类似效果。
FileOutputStream(path).use { fos ->
try {
fos.write(data)
// 你可以在这里添加更多的文件操作代码
} catch (e: IOException) {
e.printStackTrace()
// 处理异常
}
}
spring
自动加open
在springboot中使用kotlin中,由于类和类的方法默认是final的,不可继承,这会导致使用AOP机制时出现问题,可以通过第三方依赖让加了指定注解的类指定添加open关键字。
配置文档:全开放编译器插件 |Kotlin 文档 (kotlinlang.org)
<properties>
<java.version>11</java.version>
<kotlin.version>1.9.10</kotlin.version>
<spring-boot.version>2.7.6</spring-boot.version>
</properties>
<dependencies>
<!--使用kotlin需要的依赖(库和运行时环境)-->
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core</artifactId>
<version>1.7.2</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<!--allopen依赖配置好后,在加上下面spring插件的配置,可以让一些spring相关的注解自动启用allopen的功能-->
<plugin>spring</plugin>
<plugin>all-open</plugin>
</compilerPlugins>
<pluginOptions>
<!--指定有哪些注解的类自动加上open-->
<option>all-open:annotation=org.springframework.validation.annotation.Validated</option>
</pluginOptions>
<option>all-open:annotation=org.springframework.web.bind.annotation.RestControllerAdvice</option>
<option>all-open:annotation=org.springframework.context.annotation.Configuration</option>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
注:
-
<plugin>spring</plugin>
:支持的注解包括下面这些,以这些注解为元注解的注解同样生效。- @Compoent
- @Async
- @Transactional
- @Cacheable
- @SpringBootTest
-
数据类不能被继承,数据需要改为普通类并使用open才能被继承
-
Validated注解修饰参数时,参数的类型并不会自动加上open,因为kotlin-maven-allopen只作用于类级别的注解
- 解决方法:可以自定义一个注解,给对应的类加上该注解,并在allopen插件中配置好该注解
package com.example.utils
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
annotation class AutoOpen