大家都知道 Kotlin 有空安全
var s: String 代表不为空
var s: String? 代表可为空
奇葩操作来了,在我接手之前,除了绝大部分的基本变量,其余所有变量都是 String?、Objxx?
使用的时候:
if (S != null) print(s) else throw Exption("s shouldn't be null")
或者:
if (obj?.s == null) return obj!!.s
一开始很好奇这个脑残写法是怎么来的
然后遇到了一个 crash 我找到根源了。我写的代码里没有用 String? ,但是却报了 NPE ,赋值的地方都查过了,不存在 null 。最终不断地调试发现每次页面 onDestory()的时候会有个反射递归地将所有变量和变量里的变量都设置成 null (说是在手动 GC…)。又因为魔改了生命周期+协程,读取变量的时候已经是 null 了,然后报错==
!
![]() | 1 ghost024 2024-10-05 19:03:28 +08:00 哈哈哈哈哈,要么改反射,要么加入:) |
![]() | 2 nuonuojump 2024-10-05 21:01:27 +08:00 挺先进的代码,我都没想过还能在销毁的时候 手动做这种类型的 gc 。挺先进的。 |
![]() | 3 easylee 2024-10-05 21:36:01 +08:00 如此一说,Java 里面是不是也能这么操作?有实战案例吗! |
4 htxy1985 2024-10-05 23:15:12 +08:00 ![]() 手动设置为 null 这种做法只在零几年的代码里见过,还有人专门写了英文注释,感觉是跟国际水准接轨 /doge |
![]() | 5 beisilu 2024-10-06 09:17:06 +08:00 盲猜这个是在已有屎山上拉的 盲猜楼主还要再拉一坨 |
![]() | 6 300 OP |
![]() | 7 akiakise 2024-10-06 15:23:04 +08:00 via iPhone 简直就是在用 java 的方式写 kotlin ,jb 辛辛苦苦加的那么多语法糖是一口不吃啊 |
![]() | 8 300 OP @akiakise 有些地方还是吃的,但绝大多数代码都是 Java 的风格 另外我们是 Android ,官方组件几乎不用的。viewmodel 、lifecycler 什么的。自己搓了一套 lifestate ,从来没去研究过到底解决了什么问题,难懂反正 |
![]() | 9 leegradyllljjjj 2024-10-06 22:15:21 +08:00 java 就是上世纪的狗屎语言,不少遗老遗少还当宝,自诩为 java 专家称号 |
10 iseki 2024-10-07 05:42:34 +08:00 via Android 这已经不是什么语言的问题了不过我大概猜测,是不是哪里一直持有这个 activity 的引用啊,要不然怎么会想到干这种事 |
![]() | 12 lisongeee 2024-10-07 13:13:43 +08:00 ```kt if (obj?.s == null) return obj!!.s ``` 我一般不会这么写,我一般写的是 ```kt val s = obj?.s ?: return ``` 这样才能保证线程安全,最上面那种情况我只会在 js 里写,只有在 js 里这种用法才是线程安全的 (瞎写的 getter 不算) |
![]() | 13 300 OP |
![]() | 14 lisongeee 2024-10-07 13:42:10 +08:00 val s 是线程安全的,obj!!.s 是线程不安全的 如果 obj 是 val 的,并且 obj 的 s 也是 val 声明的,那 val s 和 obj.s 没区别 如果你的代码风格尽量向 immutable 靠近,那能避免很多错误,当然这是我的前端思维,我不知道是否适合后端 可以解一下 kotlinx-collections-immutable 这个库 |
![]() | 15 xuanbg 2024-10-07 13:48:09 +08:00 @leegradyllljjjj 这个和语言有什么关系啊,你给个你心目中最好的语言,我负责给你找一堆的屎来喂给你 |