当前位置: 首页 > news >正文

20260320-前五章的一些个人补充知识

之后会在这里随时补充一些知识点

一、

二、

三、

四、类与面向对象编程

4.1、android的内部类和kotlin的是不一样的定义

在java中:

public class OuterClass { // 1. 静态内部类(嵌套内部类)- 不持有外部类引用 static class StaticInnerClass { } // 2. 非静态内部类(普通内部类)- 持有外部类引用 class NonStaticInnerClass { } // 3. 匿名内部类 - 持有外部类引用 Runnable runnable = new Runnable() { @Override public void run() { } }; }
  • 静态内部类:不持有外部类引用
  • 非静态内部类:持有外部类引用
  • 匿名内部类:持有外部类引用

原理:当编译器编译非静态内部类时,会自动添加一个指向外部类的引用字段。

public class OuterClass { private int outerField = 10; class InnerClass { public void accessOuter() { System.out.println(outerField); } } } 编译后的字节码(简化): // OuterClass$InnerClass.class class OuterClass$InnerClass { // 编译器自动添加的外部类引用字段 final synthetic OuterClass this$0; // 构造函数接收外部类引用 OuterClass$InnerClass(OuterClass outer) { this$0 = outer; } public void accessOuter() { // 通过this$0访问外部类成员 System.out.println(this$0.outerField); } }
  1. 自动添加字段:编译器为每个非静态内部类添加一个this$0字段(synthetic修饰符表示这是编译器生成的)

  2. 构造函数修改:构造函数自动接收外部类引用并保存

  3. 访问外部成员:所有对外部类成员的访问都通过this$0进行

  4. synthetic 关键字:标记编译器自动生成的代码,在源代码中不可见

匿名内部类本质上是非静态内部类的一种特殊形式,因此同样持有外部类引用。

4.2、内存泄漏风险

由于非静态内部类持有外部类引用,容易导致内存泄漏:

public class Activity extends AppCompatActivity { // ❌ 错误:非静态内部类持有Activity引用 private class MyHandler extends Handler { @Override public void handleMessage(Message msg) { // 处理消息 } } // ✅ 正确:使用静态内部类 + WeakReference private static class MyStaticHandler extends Handler { private WeakReference<Activity> activityRef; MyStaticHandler(Activity activity) { activityRef = new WeakReference<>(activity); } @Override public void handleMessage(Message msg) { Activity activity = activityRef.get(); if (activity != null) { // 处理消息 } } } }

4.3、kotlin嵌套类/内部类的设计上有重要区别

Java的规则:

  • 默认的嵌套类(不加static)= 非静态内部类 → 持有外部类引用
  • 加static的嵌套类 = 静态内部类 → 不持有外部类引用

Kotlin的规则:

  • 默认的嵌套类 = 静态内部类 → 不持有外部类引用
  • 加inner关键字的嵌套类 = 非静态内部类 → 持有外部类引用

4.4、Kotlin版本的Handler内存泄漏示例:

class MyActivity : AppCompatActivity() { // ❌ 错误:加inner的内部类持有Activity引用 private inner class MyHandler : Handler() { override fun handleMessage(msg: Message) { // 处理消息 } } // ✅ 正确:默认嵌套类(静态内部类)+ WeakReference private class MyStaticHandler(activity: MyActivity) : Handler() { private val activityRef: WeakReference<MyActivity> = WeakReference(activity) override fun handleMessage(msg: Message) { activityRef.get()?.let { activity -> // 处理消息 } } } }

五、函数与函数式编程

5.1、lambda表达式

val list = listOf(1, 2, 3, 4, 5, 6, 7) list.filter { it % 2 == 1 } 因为filter()函数只有一个参数,所有括号被省略了。所以,filter()函数调用的完整写法是 list.filter ({ it % 2 == 1 }) 实际的Lambda 表达 list.filter({ it -> it % 2 == 1 })

5.2、个表达式使用

let:最常用于判空和转换

// 1. 判空 (最常用!) user?.let { // 只有 user 不为 null 时才会执行这里 println("User is safe: ${it.name}") // 使用 it 访问 } // 2. 转换 val length = "Hello".let { println(it) it.length // 返回长度 5,赋值给 length }

apply:最常用于对象初始化

场景:创建对象后,立刻给它的属性赋值

// 传统写法 val user = User("Tom", 20, "Beijing") user.city = "Shanghai" user.age = 21 // apply 写法 (更优雅) val user = User("Tom", 20, "Beijing").apply { city = "Shanghai" // 直接调用属性,前面隐含了 this. age = 21 } // apply 函数返回的是 user 对象本身,所以可以直接赋值

run:结合了 let 和 apply 的特点

场景:需要执行一段代码块,这段代码块依赖于某个对象,并且最后需要返回一个计算结果(而不是对象本身)。

val user = User("Tom", 20, "Beijing") val resultString = user.run { city = "London" // 修改属性 age = 30 "User ${name} moved to $city" // 最后一行是返回值 } println(resultString) // 输出: User Tom moved to London

also:用于"顺便做某事"

场景:在链式调用中,不想打断流程,但又想"顺便"打印个日志或做个校验。它返回对象本身,所以不影响后面的操作

val numbers = mutableListOf("one", "two", "three") numbers .also { println("添加前: $it") } // 顺便打印一下列表当前状态 .add("four")
http://www.jsqmd.com/news/514273/

相关文章:

  • 芯片为什么会“变老”?
  • 保姆级教程:用再生龙Clonezilla给Linux系统做全盘备份(含U盘启动盘制作)
  • CNN vs. RCNN:图像分类与目标检测的实战对比(附代码示例)
  • 告别‘invalid character’:一次搞懂conda版本字符串的坑与.condarc的终极写法
  • Day42综合案例--学生信息表
  • AI与Python在地球科学多源数据交叉融合中的前沿技术应用
  • 报错记录:springboot后端报错java.lang.IllegalArgumentException: Invalid character found in method name
  • 1118-Row size too large.The maximum row size for the used table type,not counting BLOBs,is 65535
  • 为M2LOrder服务配置内网穿透:实现本地开发环境的远程调试
  • Lattice3.10新手必看:从新建项目到下载程序的完整流程(附VScode编写技巧)
  • 从农业到地质:高光谱遥感数据集在不同领域的应用实例解析
  • 嵌入式函数返回值设计:0成功与错误分类工程实践
  • AI入门必看:从零开始掌握人工智能核心概念(附学习路线图)
  • Scratch编程等级考试1~4级真题解析与备考策略
  • 鸟类虚拟解剖实验平台
  • Nanbeige 4.1-3B快速部署:WSL2环境下Windows一键启动指南
  • 2026 Cinema 4D渲染引擎排名(50万+农场作业数据)+ C4D云渲染推荐
  • 含SVG的风电并网系统稳定性分析与优化
  • Android 禁止侧载将正式实施,需要等待 24 小时冷静期
  • Phi-3-vision-128k-instruct赋能STM32开发:嵌入式AI视觉应用快速原型设计
  • 永磁同步直线电机 PMLSM 矢量控制滑模控制 SVPWM 仿真模型探究
  • 直接上结论:更贴合论文写作全流程的AI论文工具,千笔·专业论文写作工具 VS speedai
  • 避坑指南:ESP32测WiFi信号强度(RSSI)和吞吐量,这几个参数设置错了等于白测
  • RS-485与 CAN电平特性分析与对比
  • 全球首个包含全工具链的运维智能体 x OpenClaw组合登场
  • ClawdBot惊艳效果:餐厅菜单照片→自动识别菜名/价格/辣度图标→生成双语点餐卡
  • 我的桌面氛围灯就靠它了:STM32F103C8T6 + PWM + 电容触摸,做一个能调亮度的迷你台灯
  • 毫米波雷达点云分割模型优化:基于PointNet的改进与性能突破
  • [特殊字符] 学生党必备!Steam游戏一键入库神器,白漂党狂喜
  • Pi0具身智能v1物流应用:自动化分拣机器人系统开发