之前写了一篇Kotlin中常量和静态方法的文章,最近有人提出一个问题,在companion object中调用外部的成员变量会调用不到,这才意识到问题,本篇文章会带着这个疑问来解决问题。

一、 object关键字

object 关键字可以表达两种含义:一种是对象表达式,另一种是 对象声明

1、对象表达式

继承一个匿名对象

val textView = findViewById<TextView>(R.id.tv)
textView.setOnClickListener(object : OnClickListener {
override fun onClick(p0: View?) {
Toast.makeText(this@TestActivity, "点击事件生效", Toast.LENGTH_LONG)
} })

上面代码其实就是我们经常要给 view 设置的点击事件,OnClickListener 事件是一个匿名类的对象,用object来修饰。

2、对象声明

object 修饰的类为静态类,里面的方法和变量都为静态的。

2.1 直接声明类
object DemoManager {
private val TAG = "DemoManager" fun a() {
Log.e(TAG,"此时 object 表示 声明静态内部类")
} }
2.2 声明静态内部类

类内部的对象声明,没有被inner 修饰的内部类都是静态的

class DemoManager{
object MyObject {
fun a() {
Log.e(TAG,"此时 object 表示 直接声明类")
}
}
}

如果需要调用 a()方法

kotlin中调用
fun init() {
MyObject.a()
}
java中调用
 MyObject.INSTANCE.a();

二、companion object

companion object 修饰为伴生对象,伴生对象在类中只能存在一个,类似于java中的静态方法 Java 中使用类访问静态成员,静态方法。

companion object {
private val TAG = "DemoManager" fun b() {
Log.e(TAG,"此时 companion objec t表示 伴生对象")
}
}

kotlin 中调用

fun init(){
b()
}

java 中调用

DemoManager.Companion.b();

companion object 相关的内容可以查阅 Kotlin中常量和静态方法 这篇文章,在这里不多在具体描述。

三、在companion object中如何调用外部的成员变量

3.1 为什么companion object 中调用不到外部成员变量
class DemoManager {
private val MY_TAG = "DemoManager" fun init(){
b()
} companion object {
fun b() {
Log.e(MY_TAG,"此时 companion objec t表示 伴生对象")
}
}
}

在上面代码中MY_TAG 是不会被调用到的。

原理很简单:

在java中我们写一个静态方法,如果需要调用成员变量,是无法调用到的

private String TAG = "MainActivity";

public static void init(){
Log.e(TAG,"init() ");
}

只有将 TAG 修改为静态成员变量才能调用到

private static String TAG = "MainActivity";

public static void init(){
Log.e(TAG,"init() ");
}

由此可以看出来,java中静态方法调用成员变量,要求成员变量必须是静态的, 在kotlin 中也是一样,所以当companion object 中调用非静态的成员变量也是调用不到的。

3.2 怎样解决才能调用到呢?
companion object {
private val MY_TAG = "DemoManager"
fun b() {
Log.e(MY_TAG,"此时 companion objec t表示 伴生对象")
}
}

将所引用的成员变量也修饰静态的,这样就可以引用到了。

Kotlin中的object 与companion object的区别的更多相关文章

  1. Kotlin中常量和静态方法

    常量 Java中: class StaticDemoActivity { public static final String LOAN_TYPE = "loanType"; pu ...

  2. JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别

    ECMAScript将对象的属性分为两种:数据属性和访问器属性.每一种属性内部都有一些特性,这里我们只关注对象属性的[[Enumerable]]特征,它表示是否通过 for-in 循环返回属性,也可以 ...

  3. 在Salesforce中可以对某一个Object的Standard Button或Link进行重写

    在Salesforce中可以对某一个Object的Standard Button或Link进行重写,来实现我们特定的逻辑过程,比如:在删除某个Object之前要判断该Object的某个Field的状态 ...

  4. TestNG中的DataProvider返回Iterator<Object[]>的妙用

    TestNG中使用DataProvider有个好处,就是: 1. 在执行用例的时候dataProvider迭代中的每组数据都是作为一个用例执行 2. 在测试数据有规律的情况下,免去了添加testXML ...

  5. SAP中的BOPF(Business Object Processing Framework)

    希望简化你的业务应用开发过程?业务对象处理框架(Business Object Processing Framework,以下简称BOPF)也许可以帮到你. BOPF是SAP Business Sui ...

  6. [转] JavaScript中in操作符(for..in)、Object.keys()和Object.getOwnPropertyNames()的区别

    ECMAScript将对象的属性分为两种:数据属性和访问器属性.每一种属性内部都有一些特性,这里我们只关注对象属性的[[Enumerable]]特征,它表示是否通过 for-in 循环返回属性,也可以 ...

  7. java 中的interface是否继承object

    首先我们从C++说起, c++可以多继承.也就是一个类型 --- class,可以继承自2个以上的父类型.多继承导致一个问题,很多人知道.例如,如果类型B,类型C均继承自类型A.然后类型D继承自类型B ...

  8. python中type、class、object之间的关系

    先看一段代码 # -*- coding:UTF-8 -*- __autor__ = 'zhouli' __date__ = '2018/11/13 18:40' a = 1 b = 'abc' pri ...

  9. Java中泛型Class<T>、T与Class<?>、 Object类和Class类、 object.getClass()和Object.class

    一.区别 单独的T 代表一个类型(表现形式是一个类名而已) ,而 Class<T>代表这个类型所对应的类(又可以称做类实例.类类型.字节码文件), Class<?>表示类型不确 ...

随机推荐

  1. Linux创建Python虚拟环境

    Linux创建Python虚拟环境 安装 pip install virtualenv 基本使用 为一个工程创建一个虚拟环境: $ cd my_project $ virtualenv venv #v ...

  2. jq简单城市二级联动实现

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. ubuntu系统下用kazam软件录制的视频不能在windows系统下播放的解决方案

    遇到问题: 在做计算机视觉课程作业,运动目标检测与跟踪时,在ubuntu系统下用kazam录制了一小段运动目标检测的视频,然后在课上展示时播放不出来,想着Mp4格式的不应该播放不出来啊.网上寻求了一番 ...

  4. gitlab-runner ---CI

    gitlab-runner: https://segmentfault.com/a/1190000007180257 https://mp.weixin.qq.com/s?__biz=MjM5MTA1 ...

  5. 第二次作业(WordCount)重制版

    Github项目地址:https://gitee.com/DamonGetup/WordCount/tree/master 基本功能: 对程序设计语言源文件统计字符数.单词数.行数,统计结果以指定格式 ...

  6. 10.Git远程仓库

    到目前为止,我们已经掌握了如何在Git仓库里对一个文件进行时光穿梭,你再也不用担心文件备份或者丢失的问题了.可是有用过集中式版本控制系统SVN的童鞋会站出来说,这些功能在SVN里早就有了,没看出Git ...

  7. mysql 约束条件 primary key 主键

    primary key字段的值不为空且唯一 约束:not null unique 存储引擎:innodb 对于innodb来说,一张表内必须有一个主键 单列做主键多列做主键(复合主键) 通常都是id字 ...

  8. 3.mysql自增的字段如何重新派逊

    alter table sales drop id;ALter table sales add id int(6) PRIMARY key not null auto_increment FIRST;

  9. EasyUI Droppable 可放置

    通过 $.fn.droppable.defaults 重写默认的 defaults. 用法 通过标记创建可放置(droppable)区域. <div class="easyui-dro ...

  10. Swagger2 生成 Spring Boot API 文档

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.本文主要介绍了在 Spring Boot 添加 Swagger 支持, 生成可自动维护的 A ...