伴生对象 ? 一个 Java 程序员来到 Kotlin 阵营。 “嗨,Kotlin。我是新来的,有静态成员可用吗?”他问。 “没有。...我是面向对象的,而静态成员不是面向对象的,” Kotlin回答。 “好吧,但我需要用于 MyClass 日志记录器,该怎么办?” “没问题,可以使用伴生对象。” “伴生对象是什么鬼?”...“它是与类绑定的一个单例对象。你可以把日志记录器放在伴生对象中,” Kotlin 如此解释。 “明白了。是这样吗?” ? “对!...明白吗?这很简单。” 我很喜欢对象声明的概念——单例是种很有用的模式。从从语言中去掉静态成员就不太现实了。我们在Java中已经使用了若干年的静态日志记录器,这是非常经典的模式。...在没有Google的帮助下尝试着写出这个伴生对象。 ? ? 集合字面量 ? 在 Java 中初始化列表需要大量的模板代码: ? 初始化 Map 更加繁琐,所以不少人使用 Guava: ?
repository : MongoExperimentsRepository 伴生对象 一个 Java 程序员来到 Kotlin 阵营。 “嗨,Kotlin。我是新来的,有静态成员可用吗?”...我是面向对象的,而静态成员不是面向对象的,” Kotlin回答。 “好吧,但我需要用于 MyClass 日志记录器,该怎么办?” “没问题,可以使用伴生对象。” “伴生对象是什么鬼?”...“它是与类绑定的一个单例对象。你可以把日志记录器放在伴生对象中,” Kotlin 如此解释。 “明白了。是这样吗?”...在没有Google的帮助下尝试着写出这个伴生对象。...这是想回归 C++ 语法吗?对于我来说,这让人感到困惑。 这里最具争议的话题是默认封闭。可能是因为 Java 程序员过度使用了继承,可能你应该在允许类被继承之前想想清楚。
这里插播一个问题,static 代码块在何时执行? 首先类加载阶段可以分为加载、验证、准备、解析、初始化、使用、卸载 七个步骤 。static 代码块就是在 初始化 阶段执行的。...下面来看看 伴生对象 。 伴生对象 你可以回想一下,你在 Kotlin 中使用过 static 关键字吗?答案肯定是没有。...伴生对象,顾名思义,就是伴随着类而存在的对象,在类加载的时候初始化。...伴生对象仍旧符合这一语义。 在 Java 中如何调用伴生对象呢?User.Companion.isMale(1) 即可。...在 Java 中就可以用 User.X.isMale(1) 了。 了解了伴生对象的本质之后,再来说两个它的其他用法。
repository : MongoExperimentsRepository 伴生对象 一位 Java 程序员来到 Kotlin 面前。 “嗨,Kotlin。我是新来的,我可以使用静态成员吗?"...我是面向对象的,静态成员不是面向对象的。” Kotlin 回答。 “好吧,但我需要 MyClass 的 logger,我该怎么办?” “这个没问题,使用伴生对象即可。” “那是什么东西?”...“这是局限到你的类的单独对象。把你的 logger 放在伴生对象中。”Kotlin解释说。 “我懂了。这样对吗?”...Maybe 很久以前就被 Scala 以 Option 引入到 JVM 世界,然后在 Java 8 中被采用为 Optional。...伴生对象 原文中说: 有时候你必须使用静态。旧版本 public static void main() 仍然是启动 Java 应用程序的唯一方式。
扩展属性允许定义在类或者kotlin文件中,不允许定义在函数中。 lambda是要作为参数被传入某方法或赋值给某变量的匿名方法的简化表现形式。...为什么要使用扩展(动机): 在Java中,有很多工具类如java.util.Collections,使用很繁琐: // Java Collections.swap(list, Collections.binarySearch...list = mutableListOf(1, 2, 3) list.swap(0, 2) MutableList泛化类型: //为在表达式中使用泛型,要在函数名前添加泛型参数!...3.伴生对象-扩展函数和属性 可为伴生对象定义扩展函数和属性: class MyClass { companion object { } //伴生对象 } fun...prototype就是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法 语法 object.prototype.name=value 实例 在本例中,我们将展示如何使用
导航 学完本篇,你将了解到以下内容: 密封类构造函数传值的使用细节; 内联函数,你应该注意的地方; 伴生对象隐藏的性能问题; lazy ,可能没你想的那么简单; apply !...伴生对象,也许真的不需要 在 Kotlin 中,我们不能像 Java 一样,随便定义一个静态方法或者静态属性。此时 companion object(伴生对象)就会派上用场。...Book 类中增加了一个伴生对象,其中有一个静态的字段 SUM_MAX。...对于和业务强关联的 key 或者 TAG ,可以选择使用伴生对象,并为其增加 const val,此时语义上的清晰比内存上的损耗更加重要,特别在复杂的业务背景下。...const val DEFAULT_MIN = 1 const val LOGIN_KEY = 99 } 2022/12/6补充 使用 kotlin 文件形式去写,这种写法属于以增加静态类的方式避免伴生对象的内存损耗
Kotlin的对象表达式可分为两种情形: 对象表达式在方法的局部范围内,或使用private修饰的对象表达式,Kotlin编译器可识别对象表达式的真实类型。...三、伴生对象和静态成员 在类中定义的对象声明,可使用companion修饰,这样该对象就变成了伴生对象。...{ println("<h${i} ${msg}</h${i} ") } } } } fun main(args: Array<String ) { //使用伴生对象所在的类调用伴生对象的方法...四、伴生对象的扩展 伴生对象也可以被扩展。如果一个类具有伴生对象,则Kotlin允许为伴生对象扩展方法和属性。..." fun main(args: Array<String ) { //使用伴生对象所在的类调用伴生对象的方法 MyClass.output("Kotlin必须学") println(MyClass.name
Kotlin 中对应 Java 的懒汉式与恶汉式 IV . Kotlin 对象 ( object ) 声明 V . Kotlin 伴生对象 ( companion object ) VI . ?...Kotlin 伴生对象 ( companion object ) ---- 1 ....伴生对象 : 类内部的对象 , 使用 companion object 修饰 , 是伴生对象 ; 是类内部的单例类 ; 2 ....伴生对象名称 : 上面单例类的 懒汉模式 , 省略了伴生对象的名称 , 这种情况下使用默认名称 Companion ; 3 ....单例调用 : 可以直接使用类调用伴生对象的方法 , 上述定义的 Student 类 及伴生对象 , Student 与 Student.Companion 是等价的 ; 因此测试时 , 下面的两个方法都是调用伴生对象的方法
1. companion object 的诞生 Scala 说,要有伴生对象。 于是 Kotlin 便有了 companion object。...而 Scala 为了完成一切皆对象的使命,以及提高与 Java 的兼容性,提出了伴生对象这个概念来代替 static 方法。随后出身的 Kotlin 也借鉴了这个概念。...companion 伴生对象是一个对象,它在类初始化时被实例化。...2. companion 的实现 在 Kotlin 中,调用 Java 的 static 方法和调用 Kotlin 的 companion object 方法是一样的: AJavaClass.staticFun...你也许还留意到实例化 Companion 使用的是一个带 DefaultConstructorMarker 入参的构造器。它出现的场景是,如果是 Kotlin 编译器生成的特殊构造器,就会带这个参数。
然而Kotlin取消了关键字static,也就无法运用静态成员的相关手段。为了弥补这方面的功能缺陷,Kotlin引入了伴生对象的概念,可以把它理解为“影子”,伴生对象之于它所在的类,仿佛是如影随形。...利用伴生对象的技术,即可间接实现静态成员的功能,前面有个代码从性别类型获得性别名称,反过来也可以从性别名称获得性别类型,这个功能便可以在伴生对象中定义一个judgeSex方法判断性别类型。...} //在类加载时就运行伴生对象的代码块,其作用相当于Java里面的static { ... }代码块 //关键字companion表示伴随,object表示对象,WildAnimal...具体到编码上面,即是在伴生对象中增加这几个常量定义,代码示例如下所示: class WildAnimalConstant(var name:String, val sex:Int = MALE) {...静态成员包括静态常量与静态方法,它们都在类的伴生对象中定义,外部可以通过类名直接使用静态成员。 点此查看Kotlin入门教程的完整目录
三、使用 @JvmStatic 注解声明静态成员 1、Java 正常访问 Kotlin 伴生对象成员 2、Java 以静态方式访问 Kotlin 伴生对象成员 一、使用 @JvmField 注解暴露...的 Companion 伴生对象 中的成员时 , 需要通过如下形式进行调用 : Kotlin类.Companion.成员属性 Kotlin类.Companion.成员函数 如果想要 在不使用 Companion...的前提下 直接调用 Kotlin 中的 Companion 伴生对象 成员 , 可以 在 companion object 中 , 使用 @JvmStatic 注解 将伴生对象中的成员 声明 为 Java...静态成员 , Java 中可以按照静态成员的方式进行访问 ; 1、Java 正常访问 Kotlin 伴生对象成员 在下面的代码中 , 在 Java 语言中访问 Kotlin 伴生对象成员 , 需要先获取...进行访问 ; 2、Java 以静态方式访问 Kotlin 伴生对象成员 在下面的代码中 , 使用 @JvmStatic 注解修饰 Kotlin 中伴生对象中的成员 , 则可以在 Java 中 以静态方式访问这些成员
在某个类中,如果某些成员变量没办法在一开始就初始化,并且又不想使用可空类型(也就是带?的类型)。那么,可以使用 lateinit 或者 by lazy 来修饰它。...伴生对象的总结 ---- 类似于 Java 中使用类访问静态成员的语法。因为 Kotlin 取消了 static 关键字,所以 Kotlin 引入伴生对象来弥补没有静态成员的不足。...可见,伴生对象的主要作用就是为其所在的外部类模拟静态成员。 注意: 每个类可以最多有一个半生对象; 使用 const 关键字修饰常量,类似于 Java 中的 static final修饰。...可以使用 @JvmField 和 @JvmStatic 类似于 Java 中调用静态属性和静态方法; 伴生对象可以扩展属性和扩展方法。...首先伴生对象中的代码是在类加载时就会执行。init代码块中的方法会按顺序放在主构造函数中,主构造函数中原来的代码会在后面执行。 9. const 和 val 有什么区别?
中使用对象表达式和对象声明进行表示 对象表达式(匿名类) 匿名类其实就是在Java中的匿名内部类。...object DataProviderManager{ fun registerDataProvider(provider:DataProvider){} } 伴生对象 类内部的对象声明可以使用companion...但是每个类的伴生对象只能有一个!?...JVM 平台,如果使用 @JvmStatic 注解,你可以将伴生对象的成员生成为真正的静态方法和字段。...//@JvmStatic 注解也可以应用于对象或伴生对象的属性, 使其 getter 和 setter 方法在该对象或包含该伴生对象的类中是静态成员。
Kotlin 的类特性 写了两篇 PWA 了,今天继续讲回 Kotlin。 Kotlin 中有很多非常好的特性,扩展方法、伴生对象、原生支持动态代理、伪多继承。今天来详细讲讲。...强转与智能转换 在 Kotlin 中,用 is 来判断一个对象是否是某个类的实例,用 as 来做强转。...Kotlin 有一个很好的特性,叫 智能转换(smart cast),在我之前的文章中也提到过。就是当已经确定一个对象的类型后,可以自动识别为这个类的对象,而不用再手动强转。...在大多数情况下,官方建议是简单地使用 包级 函数。...如果只是简单的写,直接用伴生对象返回一个 val 修饰的外部类对象就可以了,但是更多的时候我们希望在类被调用的时候才去初始化他的对象。
Java中的任何引用都可能是null,这使得Kotlin对来自Java的对象进行严格的空安全检查是不现实的。Java声明的类型在Kotlin中称为平台类型,并会被特别对待。...④ 静态方法 Kotlin将包级函数表示为静态方法。如果对这些函数使用@JvmStatic进行标注,那么Kotlin还可以为在命名对象或伴生对象中定义的函数生成静态方法。...如果使用该注解,那么编译器既会在相应对象的类中生成静态方法,也会在对象自身中生成实例方法。...();//没问题,通过单例实例调用 Obj.INSTANCE.foo();// 也没问题 @JvmStatic注解也可以被应用于对象或伴生对象的属性上,使其getter和setter方法在该对象或包含该伴生对象的类中是静态成员...internal类的成员会通过名字修饰,使其更难以在Java中被意外使用到,并且根据Kotlin规则使其允许重载相同签名的成员而互不可见。 public依然保持public。
其最主要使用的是with、run和apply这三个函数。 with函数会在Lambda表达式中提供第一个参数对象的上下文,并使用Lambda表达式中的最后一行代码作为返回值返回。...toString()方法,因为对象返回的调用对象本身,所以toString()没用,而是在之后使用。...熟练使用这些函数,能够更快地完成数据的解析方法。 静态方法 在编程中,静态方法是很重要的一环。但Kotlin弱化了静态方法这个概念,因为kotlin提供了比静态方法更好的语法特性–单例类。...object Util { fun doAction() { println("do action") } } 在Kotlin中,我们可以通过在单例类内创建方法,并在之后的代码中使用...只是Kotlin会保证Util类始终只会存在一个伴生类对象,因此调用Util.doAction2()方法实际上就是调用了Util类中伴生对象的doAction2()方法。
注解时会报错,因为没有这个无参的重载函数版本 spellBook.handleWithDefault(); } } @JvmStatic @JvmField注解还能用来以静态方式提供伴生对象里定义的值...@JvmStatic注解的作用类似于@JvmField,允许你直接调用伴生对象的函数 //互操作 class SpellBook { @JvmField val spells = "hello...// spellBook.Companion.getMAX_SPELL_COUNT(); //伴生对象的属性加了@JvmField修饰以后 int result...有关的异常检查的差异让@Throws注解解决了,在编写供Java开发者调用的Kotlin API时,要考虑使用@Throws注解。...在Java里,kotlin函数类型使用FuctionN这样的名字的接口来表示,N代表值参的数目,这样的Function接口由23个,每一个都包含一个invoke函数,专门用于调用函数类型函数 class
} 伴生对象与静态成员 kotlin 中时没有static 这种方法修饰的静态方法 所以要实现 类似于java中的静态属性就要用到伴生对象 例子: fun main(args: Array<String...(Latitude.TAG) } /** * 私有的构造方法 companion伴生对象关键字 */ class Latitude private constructor(val latitude...中如static一样调用 val TAG = "Latitude" } } 每个类可以对应一个伴生对象 伴生对象的成员全局独一份 伴生对象的成员类似Java的静态成员 静态成员考虑用包级函数...、变量替代 JvmField 和JvmStatic使用后,可以用相同的语法在Java中调用 方法重载 与Java相同,,需要注意一下几点 方法的重载与默认参数 返回值类型不能作为方法签名的一部分 只有参数列表和方法名...枚举类中定义方法,那么要在枚举对象最后加上; 这基本是Kotlin中唯一一个需要强制写;的地方 密封类 密封类与枚举的区别:前者是子类可数,后者是实例可数 密封类(Sealed Class)的子类必须和父类定义在同一个文件中
这也是我们团队转向Kotlin的原因,但是在实际的使用过程中,我们发现看似写法简单的Kotlin代码,可能隐藏着不容忽视的额外开销。...Kotlin的隐藏开销 伴生对象 伴生对象通过在类中使用companion object来创建,用来替代静态成员,类似于Java中的静态内部类。...所以在伴生对象中声明常量是很常见的做法,但如果写法不对,可能就会产生额外开销。...访问一个伴生对象的私有常量字段需要经过以下方法: 调用伴生对象的静态方法 调用伴生对象的实例方法 调用主类的静态方法 读取主类中的静态字段 为了访问一个常量,而多花费调用4个方法的开销,这样的Kotlin...对于其他类型的常量,最好在它们自己的主类对象而不是伴生对象中来存储公共的全局常量。
这里给出几个网上应用的例子,实际中使用时,再补充。 1)在 kotlin 代码中使用 Integer.class。...例如 Java 中是 String 类型的对象,要在 Kotlin 中使用的话,需要用 String? 类型来接收。 4. Kotlin 没有静态变量和静态方法。...Kotlin 的伴生对象。...可以实现静态方法和静态变量: class StringUtils { // 伴生对象 companion object { // 伴生对象实现静态变量 val...可以使用伴生对象来实现 kotlin 的单例: // 单例实现 class SingleInstance private constructor() { companion object {
领取专属 10元无门槛券
手把手带您无忧上云