十一、扩展和补充
扩展和补充
- 类与对象
- 获取类的class
- 静态属性
- 对象表达式
- 静态内部类
- 私有set方法
- 返回null类型
- 注解
- 数组属性
- 常用函数
- use函数
- spring
- 自动加open
类与对象
获取类的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? = nullprivate 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