網站首頁 編程語言 正文
通過java中互相調用和編譯后的字節碼或反編譯來分析。本質上是能夠相互轉換代碼的。
1. 對象申明:修飾class名
object className {} 的類名申明方式。
object ObjectClass {
var a = 0
fun foo(){}
}
//反編譯得到如下
/* loaded from: ObjectClass.class */
public final class ObjectClass {
public static final ObjectClass INSTANCE = new ObjectClass();
private static int a;
private ObjectClass() {
}
public final int getA() {
return a;
}
public final void setA(int i) {
a = i;
}
public final void foo() {
}
}
因此,object class
就是java中,final的class配上private構造函數,加惡漢單例INSTANCE
。
如果我們要在java中調用,還得通過MyCalss.INSTANCE.a()
來調用。
備注:想讓a()函數變成static,則通過注解@JVMStatic
注解來實現,對象變量通過@JVMField
。
object ObjectClass {
@JvmField
var a = 0
@JvmStatic
fun foo(){}
}
//反編譯成如下:
public final class ObjectClass {
@NotNull
public static final ObjectClass INSTANCE = new ObjectClass();
@JvmField
public static int a;
private ObjectClass() {
}
@JvmStatic
public static final void foo() {
}
}
2. 伴生對象:companion object
class MyClass {
companion object {
val aa = 1
fun a(){}
}
}
//反編譯為java代碼如下:
public final class MyClass {
private static final int aa = 1;
public static final Companion Companion = new Companion((DefaultConstructorMarker)null);
public static final class Companion {
public final int getAa() {
return MyClass.aa;
}
public final void a() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
在Kotlin中調用MyClass.a()
, 在Java中調用 MyClass.Companion.a();
理解第一章的object class后,再理解伴生對象事半功倍。變量是放在主類中的static變量。而函數則是伴生類(靜態內部類)中的函數。同樣的,覺得這種調用不爽,可以通過注解@JVMStatic或者@JVMField處理。
3. 對象表達式
3.1 基本用法
Thread(object :Runnable{
override fun run() {
println("hah")
}
}).start()
Collections.sort(list, object : Comparator<String?> {
override fun compare(o1: String?, o2: String?): Int {
if (o1 == null) {
return -1;
}
if (o2 == null) {
return 1;
}
return o1.compareTo(o2)
}
})
//lambda寫法
Collections.sort(list, { o1: String, o2: String ->
if (o1 == null) {
return@sort -1;
}
if (o2 == null) {
return@sort 1;
}
return@sort o1.compareTo(o2)
})
匿名內部類,也會有IDEA提示,建議改成lambda(備注2點,第一點,有的可以提示,有的不提示。第二點,與java不同,java里面箭頭后面用花括號包住即可,而kotlin不能添加{})。kotlin的lambda省略寫法很多,這里不做介紹,按照idea提示自行轉換吧。
3.2 更強大的用法
多個繼承使用,達到了超越java的匿名內部類的能力。
val superMan = object: Man("Clark"), Flyable, SuperHearing, SuperVision {
override fun hearSubtleNoises() {
}
override fun seeThroughWalls() {
}
override fun fly() {
}
}
3.3 對象表達式-直用-函數
//Object a = clas.publicFoo();
//外部只能獲取到一個object。沒有任何用處。
//推薦如下加上private。
fun publicFoo() = object {
val x: String = "y"
fun getValue() = 6
}
//私有object表達式
private fun foo() = object {
val x: String = "y"
fun getValue() = 6
}
//測試上面的代碼
fun test() {
val f = foo()
val xx = f.x
f.getValue()
}
1.5 對象表達式-直用-變量
//無法被引用內部參數,是個any
val publicValue = object {
val x: String = "y"
fun getValue() = 6
}
//可以被引用
private val privateValue = object {
val x = "aaa"
fun getValue() = 7
}
private fun test() {
privateValue.x
val v = privateValue.getValue()
}
內存泄漏研究
kotlin唯一的好處是,對于沒有引用外部類實例的情況下,在對象表達式上有所優化。
kotlin分為:
靜態內部類,內部類,匿名內部類,lambda表達式。
第一種:java內部不用static修飾,持有外部引用,對應kotlin 添加inner標記;
第二種:java內部使用static修飾,不持有外部引用,對應直接申明class的kotlin內部類;
public class Test {
int x = 1;
//《1. 內部類》:會持有外部引用。
class Inner{
void a() {
x = x + 1;
}
}
//《2. 靜態內部類》不持有外部引用
static class Inner{
void a() {
x = x + 1;
}
}
void foo() {
//new Runnable屬于《3. 匿名內部類》
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
}
void foo() {
//《4. lambda》
new Thread(() -> {
}).start();
}
class MyClass {
var aaa = "a"
//持有外部引用。
inner class NestClass {
fun a(): String {
return aaa
}
}
//不持有外部引用,相當于static final class
class NestClass {
fun a(): String {
return aaa
}
}
}
原文鏈接:https://blog.csdn.net/jzlhll123/article/details/126593235
相關推薦
- 2023-06-13 C語言中函數返回值不一致問題_C 語言
- 2022-09-13 Python運算符的應用超全面詳細教程_python
- 2023-02-05 如何用C#獲取計算機詳細的軟件和硬件信息_C#教程
- 2022-10-23 C#中數組擴容的幾種方式介紹_C#教程
- 2022-08-16 QT布局管理詳解QVBoxLayout與QHBoxLayout及QGridLayout的使用_C 語
- 2022-04-02 Python操作word文檔的示例詳解_python
- 2022-10-09 玩轉Go命令行工具Cobra_Golang
- 2022-10-24 vscode使用Eslint+Prettier格式化代碼的詳細操作_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支