Kotlin伴生对象及其字节码内幕详解
继续面向对象,开撸就是!!
接口:
我们知道对于JDK8之后接口中除了方法的声明之后还可以有default方法的,而在Kotlin中也类似,下面来看一下在Kotlin接口相关的东东:

很显然就是一个方法的声明,接着:

这是方法的具体实现,跟JDK8中的默认方法差不多,只不过在Koltin中的接口中定义具体方法之前不需要用default关键字来声明而已,下面在里面打印一句话:

接下来咱们可以在实现类中来复写接口中实现的方法,如下:

接下来问题来了:既然一个类既可以实现一个接口,又能继承一个类,那如果都定义的是同一个方法,那子类覆写的到底是接口中的方法还是类中的方法呢?下面来试一下:


所以:

接下来提个需求,在C中重写方法中需要融合接口A和类B方法的功能该怎么办呢?如下:

抽象类:
它跟Java类似,所以说明一上语法既可,如下:

伴生对象【companion object】:
在这是Kotlin的新概念,主要也是为了解决某个问题而存在的,具体解决啥问题先不说,因为需要有一些前置的概念先要了解,“object declaration 对象声明”,具体怎么定定义呢?

这就声明了一个对象,而在对象里面也可以像类一样声明属性和方法,如下:

那如何调用它呢?既然已经是对象了,那不直接用.的方式去调用就行了?是的~~不用像class那样还得先生成实例再调用之,如下:

其实有点像JavaScript,任何皆对象。好,学它的目的是为了要学习“伴生对象”而做准备,在Java中是完全没这个概念的,但是!!在像Scala这样的语言也是存在的,那啥叫“伴生对象”呢?其实得从Java的static说起, 我们知道被static修饰的成员变量或者方法是用Class直接去调用的,那是不是跟我们说的定义的对象有点类似,在Kotlin中,与java不同的是,类是没有static方法的,那么问题来了,那在Kotlin中如何表达static的这种作用呢?其实是这样:在大多数情况下,Kotlin推荐的做法是使用包级别的函数来作为静态方法,Kotlin会将包级别的函数当做静态方法来看待。那问题又来了,说的这个包级别的函数跟咱们已经学习的对象声明和既将要学习的伴生对象又有何关系呢?所谓“伴生”其实就是存在于类中的一个对象,它是随类一起伴生的,讲了这么多下面来瞅下它的真面目:

然后在伴生对象里面定义的东东跟在类中定义的差不多,如下:

那这个伴生对象如何使用呢?如下:

直接可以通过类来访问伴生对象里面的方法,但是!!貌似跟java中的static还是没联系上呀,下面再来演变:


这就是伴生对象所起到的作用,可以达到java中的static的效果。
接下来再来脑洞一个情况:假如一个类中有多个伴生对象,而且伴生对象中有相同的方法,那我们直接用类去访问这个方法调的是哪个伴生对象中的方法呢?其实Kotlin已经为我们杜绝了这种可能性,也就是一个类只能有一个伴生对象,不信咱们试试:

另外还有一个细节,就是伴生对象的名字其实是可以省略掉的:

其中报错的需要这样改就不会报错了:

所以“如果不提供伴生对象的名字,那么编译器会提供一个默认的名字叫Companion”,下面咱们还是将伴生对象名称还原:

至此对于Kotlin的伴生对象的使用就已经学完了,但是!!还是有个疑问:它怎么就能实现static的效果呢?编译生成的字节码中是不是真正给加上一个static的关键字呢?好!!接下来就开始对它进行揭密:先来将这个伴生对象给打印一下,看它倒底是啥?

所以需要注意:“虽然伴生对象的成员看起来像是Java中的静态成员,但是在运行期,他们依旧是真实对象的实例成员【因为属于伴生内部对象中的方法,伴生对象在编译后会生成一个静态内部类】”,但是在JVM上,可以将伴生对象的成员真正生成为类的静态方法与属性,这是通过@JvmStatic注解来实现的,如下:

那说是这么说,如何来验证所说的观点呢?其实很简单,查看一下所生成的字节码就知晓了,所以下面来正式探究原理,先来查看一下当前生成类的字节信息,咱们先来看不加@JvmStatic注解的字体码情况:


进一步查看字节信息:

这也论证了“虽然伴生对象的成员看起来像是Java中的静态成员,但是在运行期,他们依旧是真实对象的实例成员【因为属于伴生内部对象中的方法,伴生对象在编译后会生成一个静态内部类】”,好,接下来加上@JvmStatic注解,再来看一下字节码的情况:


真正成为了Mytest中的静态方法了,这也就是这个注解的作用,下面来看一下该注解的说明:

再来看一下详细的字节情况:

接下来为了更加清晰的了解,再定义一个类,再查看一下它的字节码信息:


下面调用一下:

所以说,了解一定的Java字节码的知识有助于了解底层~~
Kotlin伴生对象及其字节码内幕详解的更多相关文章
- Java Class 字节码文件结构详解
Class字节码中有两种数据类型: 字节数据直接量:这是基本的数据类型.共细分为u1.u2.u4.u8四种,分别代表连续的1个字节.2个字节.4个字节.8个字节组成的整体数据. 表:表是由多个基本数据 ...
- [转]C语言字节对齐问题详解
C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...
- Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 关于RPC(Remote Procedure Call),如果没有概念,可以参考一下RMI(Remot ...
- Hadoop3.1.1源码Client详解 : 入队前数据写入
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 紧接着上一篇: Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立 先给出 ...
- NopCommerce源码架构详解--初识高性能的开源商城系统cms
很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...
- HTTP 状态响应码 意思详解/大全
HTTP 状态响应码 意思详解/大全 转:http://blog.csdn.net/helin916012530/article/details/29842595 HTTP状态码(HTTP Statu ...
- NopCommerce源码架构详解
NopCommerce源码架构详解--初识高性能的开源商城系统cms 很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...
- Nop--NopCommerce源码架构详解专题目录
最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...
- Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之ResponseProcessor(ACK接收)
该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 紧接着上一篇文章: Hadoop3.1.1源码Client详解 : Packet入队后消息系统运作之D ...
随机推荐
- [LeetCode] 224. Basic Calculator 基本计算器
Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...
- kubernetes之secret
Secret解决了密码.token.密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中.Secret可以以Volume或者环境变量的方式使用. Secret类型: Opa ...
- 【视频开发】CximageMat 、CximagelplImage 以及 lplImageMat的转换、像素位深度
1.传统的lplImage * -------> Mat格式 IplImage* img = cvLoadImage("greatwave.png", 1); Mat mtx ...
- Java中缓存的介绍
一.什么是缓存1.Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问2.凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之 ...
- CSP2019-终章:afo生活的开始
出分了...退役了...449...afo了... 曾经立志不少于500的我...竟然450都没上... Orz初中的神仙学弟考了596... 接下来,是一种生活的结束,也是另一种生活的开始... 我 ...
- php_MVC实现步骤二
2.match_split 显示逻辑相分离 将功能强制分成两个部分,显示html文件,和逻辑PHP文件: 要求浏览器请求负责功能的PHP逻辑文件: 该PHP逻辑文件,对需要的显示内容进行载入. 逻辑P ...
- 学习数据结构Day3
栈和队列 栈是一种线性结构,相比数组 他对应的操作是数组的子集 只能从一端进入,也只能从一端取出 这一端成为栈顶 栈是一种先进后出的数据结构,Last In First Out(LIFO) 程序调用的 ...
- TCP协议的11种状态及其变化过程?传输的内容又是什么?
在TCP的11种状态变迁中,我们需要用到TCP头部的三个标志位: 1.SYN,SYN=1表示这是一个连接请求报文或者连接接受报文 2.ACK,ACK=1,表示确认号生效 3.FIN,FIN=1表示发送 ...
- [Oracle] Io Error: The Network Adapter could not establish the connection 解决方案
Io 异常: The Network Adapter could not establish the connection这个异常的出现一般与数据库和你的PC的设置有关 这种异常的出现大致上有下面几种 ...
- Java开发笔记(一百一十七)AWT窗口
前面介绍的所有Java代码,都只能通过日志观察运行情况,就算编译成class文件,也必须在命令行下面运行,这样的程序无疑只能给开发者做调试用,不能拿给一般人使用.因为普通用户早已习惯在窗口界面上操作, ...