IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Kotlin object的用法和内存泄漏研究 -> 正文阅读

[移动开发]Kotlin object的用法和内存泄漏研究

通过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
        }
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:23:00  更:2022-09-04 01:23:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:30:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码