新项目搞起耍, 记录部分问题备查
目录
1. Kotlin 使用 Spring boot
@SpringBootApplication
open class LocationClientApp
fun main(args: Array<String>) {
SpringApplication.run(LocationClientApp::class.java, *args)
}
2. Kotlin 构造函数
Kotlin Primary Constructor
主构造函数可以不显式声明, kotlin 编译器会为我们默认创建一个。
// 不显式声明
class 类名{
}
// 标准写法
class 类名 constructor(形参1, 形参2, 形参3){
...
}
// 简写
class 类名(形参1, 形参2, 形参3){
...
}
// 使用 init 初始化代码块来为 Primary Contructor 服务
init{
val 变量 = 形参1
...
}
Kotlin Secondary Constructor
次级构造函数定义在类的内部,可以定义多个,它们会直接或间接调用主构造方法,如果自定义了主构造方法,需要使用 :this 方式调用主构造方法
class 类名 constructor(){
init{...}
// Secondary Constructor
constructor(形参...):this(){
...
}
}
父类构造函数
父类构造函数可以在什么主构造函数时声明,也可以在定义次级构造函数时使用 :super 方式调用
// 使用主构造函数
class FrameReadHandle(byteOrder: ByteOrder?,
maxFrameLength: Int,
lengthFieldOffset: Int,
lengthFieldLength: Int,
lengthAdjustment: Int,
initialBytesToStrip: Int,
failFast: Boolean) : LengthFieldBasedFrameDecoder(byteOrder,
maxFrameLength,
lengthFieldOffset,
lengthFieldLength,
lengthAdjustment,
initialBytesToStrip,
failFast) {
// 使用次级构造函数
constructor(byteOrder: ByteOrder,
maxFrameLength: Int,
lengthFieldOffset: Int,
lengthFieldLength: Int,
lengthAdjustment: Int,
initialBytesToStrip: Int,
failFast: Boolean) : super(byteOrder,
maxFrameLength,
lengthFieldOffset,
lengthFieldLength,
lengthAdjustment,
initialBytesToStrip,
failFast)
3. Kotlin 使用 Java 方法中泛型
public Jackson2JsonRedisSerializer(Class<T> type)
// 示例 1
val jackson2JsonRedisSerializerForValue = Jackson2JsonRedisSerializer(Object::class.java)
// 示例 2
val jackson2JsonRedisSerializerForValue = Jackson2JsonRedisSerializer(LocationResultVO::class.java)
4. Kotlin Spring 依赖注入报错 NoClassDefFoundError KClasses
错误信息:
java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses
添加依赖
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
<version>${kotlin.version}</version>
</dependency>
5. Kotlin 实现 Java 静态变量、方法、初始化和内部类
- Java 的静态变量和方法,在 Kotlin 中使用伴生对象替代
companion object {
val zoneId = ZoneId.of("Asia/Shanghai")
}
// 类内部使用,直接使用
recordTime = LocalDateTime.now(zoneId)
// 类外使用,使用类名
var zoneId = LocationResult.zoneId;
- Java 的静态初始化,在 Kotlin 中使用伴生对象的 init 替代
companion object {
val zoneId:ZoneId
// 使用 init
init{
zoneId = ZoneId.of("Asia/Shanghai")
}
}
- Java 的静态内部类,在 Kotlin 中使用嵌套类来替代
Kotlin 的内部类(使用 inner 修饰符)相当于 Java 的普通内部类,可以访问外部变量,同时持有外部对象的引用。
class StaticTest {
var out = 0
inner class InnerClass{
fun InnerClassMethod(){
out = 100 //内部类可以访问外部变量
}
}
}
Kotlin 的嵌套类(没有 inner 修饰符)相当于 Java 的静态内部类,不可以访问外部变量
class StaticTest {
var out = 0
class InnerClass{
fun InnerClassMethod(){
out = 100 //编译错误,嵌套类不可以访问外部变量
}
}
}
6. Kotlin 匿名内部类
kotlin 匿名内部类使用 object 关键字来实现,其他的几乎和 Java 语言相同。
b.handler(object : ChannelInitializer<Channel>() {
override fun initChannel(ch: Channel) {
ch.pipeline().addLast(MessageWriter())
}
})
7. kotlin 函数
kotlin 函数定义方式与 Java 不同
- 使用 fun 关键字
- 参数可以设置默认值,构造函数中也可以设置默认值
// 一个标准格式
访问控制符 fun 方法名(参数=默认值,...) : 返回类型{
...
}
8. Kotlin 一键生成 log
-
Template text:
companion object {
val log: Logger = LoggerFactory.getLogger($CLASSNAME$::class.java)
} -
variable Expression
groovyScript("_1 ?: ‘<top>’", kotlinClassName())
9. Kotlin Spring 配置
数组配置使用 [ ] 完成, 如下排除自动配置 DataSource
@SpringBootApplication(exclude = [DataSourceAutoConfiguration::class])
@EnableAsync
open class TestApp
10. Kotlin 判断 lateinit var 是否初始化
// 判断 variable 是否初始化
if (!this::variable.isInitialized) {
...
}
需要注意的是变量前面一定要加上this::
,不然会提示找不到"isInitialized"这个方法。