網(wǎng)站首頁 編程語言 正文
通過java中互相調(diào)用和編譯后的字節(jié)碼或反編譯來分析。本質(zhì)上是能夠相互轉(zhuǎn)換代碼的。
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構(gòu)造函數(shù),加惡漢單例INSTANCE
。
如果我們要在java中調(diào)用,還得通過MyCalss.INSTANCE.a()
來調(diào)用。
備注:想讓a()函數(shù)變成static,則通過注解@JVMStatic
注解來實現(xiàn),對象變量通過@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中調(diào)用MyClass.a()
, 在Java中調(diào)用 MyClass.Companion.a();
理解第一章的object class后,再理解伴生對象事半功倍。變量是放在主類中的static變量。而函數(shù)則是伴生類(靜態(tài)內(nèi)部類)中的函數(shù)。同樣的,覺得這種調(diào)用不爽,可以通過注解@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)
})
匿名內(nèi)部類,也會有IDEA提示,建議改成lambda(備注2點,第一點,有的可以提示,有的不提示。第二點,與java不同,java里面箭頭后面用花括號包住即可,而kotlin不能添加{})。kotlin的lambda省略寫法很多,這里不做介紹,按照idea提示自行轉(zhuǎn)換吧。
3.2 更強大的用法
多個繼承使用,達到了超越j(luò)ava的匿名內(nèi)部類的能力。
val superMan = object: Man("Clark"), Flyable, SuperHearing, SuperVision {
override fun hearSubtleNoises() {
}
override fun seeThroughWalls() {
}
override fun fly() {
}
}
3.3 對象表達式-直用-函數(shù)
//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 對象表達式-直用-變量
//無法被引用內(nèi)部參數(shù),是個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()
}
內(nèi)存泄漏研究
kotlin唯一的好處是,對于沒有引用外部類實例的情況下,在對象表達式上有所優(yōu)化。
kotlin分為:
靜態(tài)內(nèi)部類,內(nèi)部類,匿名內(nèi)部類,lambda表達式。
第一種:java內(nèi)部不用static修飾,持有外部引用,對應(yīng)kotlin 添加inner標記;
第二種:java內(nèi)部使用static修飾,不持有外部引用,對應(yīng)直接申明class的kotlin內(nèi)部類;
public class Test {
int x = 1;
//《1. 內(nèi)部類》:會持有外部引用。
class Inner{
void a() {
x = x + 1;
}
}
//《2. 靜態(tài)內(nèi)部類》不持有外部引用
static class Inner{
void a() {
x = x + 1;
}
}
void foo() {
//new Runnable屬于《3. 匿名內(nèi)部類》
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
}
}
//不持有外部引用,相當(dāng)于static final class
class NestClass {
fun a(): String {
return aaa
}
}
}
原文鏈接:https://blog.csdn.net/jzlhll123/article/details/126593235
相關(guān)推薦
- 2023-03-28 Python中的len()函數(shù)是什么意思_python
- 2022-10-15 詳解C++中常用的四種類型轉(zhuǎn)換方式_C 語言
- 2022-09-04 python接口自動化之正則用例參數(shù)化的示例詳解_python
- 2022-08-10 C++中string字符串分割函數(shù)split()的4種實現(xiàn)方法_C 語言
- 2022-05-28 Pyinstaller打包Pytorch框架所遇到的問題_python
- 2022-01-15 跨域系列之proxy代理,解決跨域的方法之一
- 2022-02-20 千分位保留兩位小數(shù),出現(xiàn)“toFixed() is not a function”的解決辦法
- 2022-04-04 react Ant Design使用a標簽href屬性警告解決方法
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支