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

Kotlin和Java在匿名内部类和接口的使用中的区别及对比

1、Kotlin中使用匿名内部类和接口:

interface ITest {fun test(param: Int) {Log.e("zxy99999", "::ITest:test:param:$param")}fun test222(param: Int) {Log.e("zxy99999", "::ITest:test222:param:$param")}
}var mITest: ITest? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)initTest()btn.setOnClickListener {mITest.test()}btn222.setOnClickListener {mITest.test222()}}private fun initTest() {var count = 0/***** 一、在匿名内部类中使用局部变量 *****/mITest = object: ITest {override fun test(param: Int) {count++Log.e("zxy99999", "::initTest 回调test方法,count:$count, param:$param")super.test(param + count)}override fun test222(param: Int) {count++Log.e("zxy99999", "::initTest 回调test222方法,count:$count, param:$param")super.test222(param + count)}}/***** 二、为了观察局部变量的变化,在延时任务中使用局部变量 *****/     Handler().postDelayed({count = count + 300Log.e("zxy99999", "::5秒之后 initTest count:$count")}, 10000)
}

2、Java中使用匿名内部类和接口:

public class TestObj {abstract class ITest {public void test(int param) {Log.e("zxy99999", "::ITest:test:param:" + param);}public void test222(int param) {Log.e("zxy99999", "::ITest:test222:param:" + param);}}ITest mITest = null;public TestObj() {super();}int outCount = 0;public void initTest() {int count = 0;mITest = new ITest() {@Overridepublic void test(int param) {outCount++;count++;   // 会报错 Variable 'count' is accessed from within inner class, needs to be final or effectively finalsuper.test(param + count);}@Overridepublic void test222(int param) {super.test222(param);}};new Handler().postDelayed(new Runnable(){@Overridepublic void run() {outCount = outCount + 300;count = count + 300; // 会报错,Variable 'count' is accessed from within inner class, needs to be final or effectively final}}, 10000);}
}
区别一:接口

Kotlin 的接口中可以直接实现方法,这是 Kotlin 接口与 Java 早期版本接口的重要区别(Java的接口中是不能实现方法的,Java 8+ 才通过 default 关键字支持类似功能)。

Kotlin 接口中方法的两种形式

  • 抽象方法(无实现)只声明方法签名,没有方法体,必须由实现接口的类重写。
  • 具体方法(有实现)直接定义方法体,实现接口的类可以直接继承使用,也可以选择重写。
区别二:匿名内部类中引用方法中的局部变量

在 Kotlin 中,当局部变量被匿名内部类或 lambda 捕获并修改时(如代码中的 count),编译器会将其包装为堆内存中的可变对象,此时不会再对原局部变量保存副本,而是通过共享这个包装对象实现变量的统一访问。

具体原因分析
  • 包装的本质是 “共享容器”编译器生成的包装对象(可理解为一个持有 count 实际值的容器)是唯一的,匿名内部类、延迟任务以及原方法中的 count 引用,最终指向的是同一个包装对象。
    原方法中对 count 的修改(如 count = count + 300),本质是修改包装对象内部的值。
    匿名内部类中对 count 的修改(如 count++),也是修改同一个包装对象内部的值。
    因此,不存在 “副本”,所有操作都作用于同一个数据源。
  • 与 Java 中 “不可变局部变量” 的区别在 Java 中,若局部变量被匿名类捕获且不可变(final),编译器会为匿名类生成一个值的副本(因为变量不会被修改,副本不影响一致性)。但 Kotlin 中允许捕获可变局部变量(无需 final),此时必须通过包装对象实现共享修改,而不是副本(否则会导致原变量和匿名类中的副本值不一致)。

以上解释来自豆包。

http://www.dtcms.com/a/517271.html

相关文章:

  • mysql做网站怎么查看数据库坪山住房及建设局网站
  • 河北省建设局网站网站建设公司深圳
  • Request method ‘POST‘ not supported,问题分析和解决
  • KH|记录KingHistroian4.0卸载过程
  • Spring MVC 接口匹配性能优化:.do后缀引发的性能瓶颈分析
  • ps图做ppt模板下载网站有哪些创意设计生活用品
  • Windows API 文件结构与功能分类详解
  • 网站建设费开票收候开在哪个类别里做用户名验证的网站服务器
  • 常熟制作网站的地方wordpress解决速度慢
  • 自己可以做网站推广吗最新的新闻 最新消息
  • Redis不停机升级5.0.3->8.0.4
  • 做网站语言排名2018网站开发的方法和步骤
  • 网页设计入门首先要学什么企业网站优化与推广
  • 抓住园艺消费升级!亚马逊卖家如何从“卖单品”升级为“做品牌”
  • FPGA-ZYNQ学习对BD的保存与应用
  • 博罗县建设局网站免费好玩的网页游戏
  • 强化运动控制领域布局,杰美康机电授权世强硬创代理
  • 容器适配器、关联容器的相关算法题目
  • 微网站的好处优秀产品设计公司哪家好
  • 树莓派Pico 2W 开发环境搭建
  • 零基础从头教学Linux(Day 54)
  • Dexmal原力灵机发布Dexbotic,从此具身智能研发有了“加速器”
  • 电子商务网站建设步网页打不开验证码图片
  • 怎样做自己的微商网站个人网站备案建设方案书
  • 《用于触觉感知的电阻式传感器技术的最新进展》IEEE SENSORS 2022综述文章解读
  • Redis vs RabbitMQ 对比总结
  • 初识C语言11.数据在内存中的存储
  • 操作系统存储管理核心知识点与例题详解
  • 人工智能风险与伦理(3)
  • the scientist and engineer‘s guide to DSP:5 Linear Systems