超干货详解:kotlin(4)-java转kotlin潜规则

本文从老鸟视角探讨Java到Kotlin的重构,重点介绍Kotlin的重难点,如lambda、高阶函数、泛型、集合操作和协程,以及Java转Kotlin的潜规则,如文件和类的关系、共生体、修饰符和空指针问题。通过实例解析,帮助开发者理解Kotlin在实际开发中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以一个java老鸟的角度,如何去看 kotlin。 Java源代码应该如何用Kotlin重构。 如何正确学习kotlin并且应用到实际开发中。本文将会探究。

本文分两大块,重难点和潜规则。

重难点:Kotlin中可以独立出来讲解的大块知识点。提供单独Demo。这部分大多数是Kotlin开创的新概念(相比于Java)。

潜规则:Kotlin是谷歌用来替换Java的,它和java百分百完全兼容,但是实际上java转成kotlin之后,需要我们手动修改很多东西,甚至某些部分必须打散重构来达到最优编码。其中,kotlin的某些特性和java不同,甚至完全反转。这部分知识点比较零碎,单独Demo不方便提供,就以小例子的形式来写。

  • 重难点

  • lambda以及操作符

  • 高阶函数以及操作符

  • Kotlin泛型

  • 集合操作

  • 协程

  • 操作符重载

  • 潜规则

  • Kotlin文件和类不存在一对一关系

  • 共生体

  • 继承

  • 修饰符

  • 空指针问题

潜规则

从Java转到kotlin,基本上都会存在java代码与kotlin共存的问题。而且为了快速转型,可能会直接把java类转成kotlin类,而这个过程中,涉及到java和kotlin的交互,往往会磕磕碰碰,以下总结了一部分 java kotlin交互方面的问题.

Kotlin文件和类不存在一对一关系

kotlin的文件,可以和类名一致,也可以不一致。这种特性,和c++有点像,毕竟c++的.h 和 .cpp文件是分开的。只要最终编译的时候对的上,文件名其实无所谓的。Java中,一个类文件的类名和文件名不一致,如果是public类,就会报异常。

在kotlin中,可以写成一致,如:

不一致:

这样做的意义在于:

如果有很多个行数很短的类:在java中可能要占用大量的文件个数(Java中可以用内部类的形式解决),kotlin中则可以把这些类都放到同一个kt文件中,不用内部类也能解决。

共生体

Java中的静态 static关键字,在kotlin中不复存在,作为替换,Kotlin提出了共生体的概念。如果是kt文件去调用kt类的“静态”方法(不依赖对象),则要求后者的类结构中增加一个 companion object 成员变量。并且可以在 成员中写上 你想要定义的"静态"成员变量和成员方法

class Test001(_name: String) : Person(_name) {
companion object {
const val s: String = “”
const val s2: String = “”

fun t1(){

}
}
}

fun main(){
Test001.s
Test001.t1()
}

注:每一个kotlin类中,只能有一个共生体对象.

但是在java调用kt的"静态"成员方法时,必须带上共生体,但是,访问"静态"成员变量,则不能带:

public static void main(String[] args) {
Test001.Companion.t1();//Java访问kt的t1()共生体方法,必须带上Companion
String s2 = Test001.s;// 而访问共生体成员变量,不能带Companion
}

好纠结。为什么要这么设计。算了。查了一下kt反编译之后的Java源码:

共生体变成了Java类中的静态内部类,包含t1()方法。而s,s2 则是普通的静态变量。

修饰符

修饰符指的是 类 和 成员变量,成员方法 前面的 权限访问关键字。原 Java拥有 private ,protected,default ,public ,访问权限分别为: 本类内部,同包名或子类,同包名,全局。

然而,kotlin新增了一个概念,internal ,表示,相同Module内可访问,跨Module则不行。

并且,java和kotlin的 private ,protected,default ,public 的访问权限还有区别,但是我这里就不详述了,因为我觉得意义不大。能不能访问,写代码的时候编译器会告诉你,当场警告你,你就会修改代码。如果有问题。可以把kotlin Decompile成Java代码自己去对比试试。如有需要,后期再说吧。

空指针问题

通常要快速的将 旧java代码转化成kotlin代码,是拷贝java代码粘贴到kotlin文件内,让as自动转化,但是这种方式,容易造成很多空指针问题,有一些是很直白的报了编译错误,而有一些则是隐藏起来,等到程序运行时才会报错。直接报错的就不提了,下面演示隐藏的空指针问题:

Kotlin类:

class Student(name:String) {
var name: String = name

fun showName(tag: String) {
println(“$tag : $name”)
}
}

Java调用kt:

public class Main {
public static void main(String[] args) {
Student s = new Student(“zhou”);
s.showName(null);
}
}

此时,如果运行main函数,就会报出:

告诉我们参数tag不可为null。但是奇怪的是,在java代码中,居然不会报编译错误。贼特么诡异。

解决方案:

在方法参数后面加上问号,变成这样:

没有基本数据类型

Kotlin之中没有基本数据类型,它只有:
Int,Short,Long,Float,Double,Byte ,Char,Boolean 这样的包装类型。
为什么没有?没有必要去纠结,但是只提供包装类型有一个好处,那就是 方便扩展函数的定义。
我们可以很轻松地对 Int,类型去扩展函数。
比如: Kotlin自带了很多扩展函数:

这是系统定的,我们也可以自己来定义:

fun Int.plus100(): Int {//自定义扩展
return this + 100
}
fun main() {
val a: Int = 20
println(“${a.plus100()}”)
}

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

写在最后

作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动?

就目前大环境来看,跳槽成功的难度比往年高很多。一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。

最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf”(实际上比预期多花了不少精力),包含分布式架构、高可扩展、高性能、高并发、Jvm性能调优、Spring,MyBatis,Nginx源码分析,Redis,ActiveMQ、Mycat、Netty、Kafka、Mysql、Zookeeper、Tomcat、Docker、Dubbo、Nginx等多个知识点高级进阶干货!

由于篇幅有限,为了方便大家观看,这里以图片的形式给大家展示部分的目录和答案截图!

Java经典面试问题(含答案解析)

阿里巴巴技术笔试心得

有限,为了方便大家观看,这里以图片的形式给大家展示部分的目录和答案截图!**
[外链图片转存中…(img-K9LaqHGd-1710433942507)]

Java经典面试问题(含答案解析)

[外链图片转存中…(img-GMKPtHhH-1710433942508)]

阿里巴巴技术笔试心得

[外链图片转存中…(img-iPODf6n1-1710433942508)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

安卓报错Duplicate class org.jetbrains.org.objectweb.asm.util.CheckSignatureAdapter$State found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.Printer found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.Textifiable found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.Textifier found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceAnnotationVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceClassVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceFieldVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceModuleVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10) Duplicate class org.jetbrains.org.objectweb.asm.util.TraceSignatureVisitor found in modules jetified-kotlin-compiler-embeddable-1.4.10 (org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.10) and jetified-kotlin-gradle-plugin-1.4.10 (org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10)
最新发布
04-01
<think>嗯,用户遇到了安卓项目中的重复类错误,涉及多个org.jetbrains.org.objectweb.asm.util下的类。首先,我需要理解这个问题的根本原因。错误信息显示,kotlin-compiler-embeddable和kotlin-gradle-plugin这两个依赖包含了相同的类,导致冲突。这可能是因为这两个库都依赖了不同版本的ASM库,或者它们内部打包了相同类但不同版本。 接下来,我应该考虑常见的解决方法。通常,这类问题可以通过排除重复的依赖来解决。用户需要在构建文件中检查这两个模块的依赖关系,找出哪个模块引入了冲突的ASM类,然后排除掉其中一个。不过,用户提到这两个模块都是来自Kotlin的1.4.10版本,可能这时候需要确认Kotlin插件和Gradle版本是否兼容,或者是否需要升级到更高版本,因为旧版本可能存在已知的依赖冲突问题。 另外,可能需要检查项目中的其他依赖是否间接引入了不同版本的ASM库。使用Gradle的依赖树分析工具(如./gradlew app:dependencies)可以帮助识别冲突的来源。如果发现有多个版本的ASM,可以强制指定使用某个版本,或者排除其他版本。 还有可能是Gradle插件本身的问题,尤其是在使用旧版本的Kotlin插件时。查看官方文档或问题追踪系统,看看是否有相关的问题和解决方案。例如,升级到Kotlin 1.5或更高版本可能已经修复了这个问题,因为JetBrains可能在后续版本中调整了依赖管理。 用户还需要确认项目的Gradle配置是否正确,比如是否在多个地方重复声明了Kotlin插件,或者是否有第三方库强制覆盖了ASM的版本。有时候,插件之间的兼容性问题也会导致此类错误,需要逐一排查。 最后,如果排除依赖或升级版本无效,可能需要更深入分析依赖树,或者寻求社区和官方支持。提供详细的错误日志和构建文件配置会有助于更准确地定位问题。</think>这个错误是由于项目中存在重复的类定义导致的,具体涉及两个Kotlin相关模块中的ASM工具类冲突。以下是逐步分析和解决方案: **根本原因分析** 1. 冲突模块:`kotlin-compiler-embeddable`和`kotlin-gradle-plugin`都包含`org.jetbrains.org.objectweb.asm.util`包下的同名类 2. 典型触发场景:当使用较旧版本的Kotlin插件(如1.4.x)时,其内部依赖的ASM库存在重复打包 **解决方案步骤** 1. **统一Kotlin版本** ```gradle // 在项目根build.gradle中确保所有Kotlin组件版本一致 buildscript { ext.kotlin_version = '1.8.22' // 推荐使用1.7.20+ dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } ``` 2. **排除重复依赖** ```gradle // 在app模块的build.gradle中添加排除规则 configurations { all*.exclude group: 'org.jetbrains.org.objectweb.asm', module: 'asm-util' all*.exclude group: 'org.jetbrains', module: 'kotlin-compiler-embeddable' } ``` 3. **强制使用统一ASM版本** ```gradle // 在项目根build.gradle中添加全局约束 configurations.all { resolutionStrategy { force 'org.ow2.asm:asm:9.4' force 'org.ow2.asm:asm-util:9.4' } } ``` 4. **清理构建缓存** ```bash ./gradlew cleanBuildCache ./gradlew --stop rm -rf $HOME/.gradle/caches/ ``` **验证方法** 1. 查看依赖树: ```bash ./gradlew :app:dependencies --configuration runtimeClasspath ``` 2. 确认输出中不再出现`Duplicate classes`警告 **升级建议** - 若项目允许,建议升级到Kotlin 1.8.x+,该问题在较新版本中已通过优化依赖管理得到解决 - 检查Android Gradle Plugin版本是否与Kotlin版本兼容(参考官方兼容性文档) **技术背景** 该问题源于Kotlin编译器内部使用的ASM库(Java字节码操作框架)在多个子模块中的重复打包。在构建时,Gradle的依赖解析器会发现同一类的多个实例,违反JVM的类唯一性原则。通过依赖排除和版本强制可以确保类加载器只获取单一版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值