绝对干货 | Kotlin内联类工作原理及使用案例,看完你会回来谢我的

STC8G1K08A 实战应用:从配置到功能实现 本文详细介绍了STC8G1K08A单片机的实战应用,从开发环境搭建、GPIO配置、ADC模块使用到定时器中断处理和PWM输出等核心功能。重点讲解了外设模块的协同工作配置技巧,并分享了实际项目开发中的经验教训,帮助开发者快速掌握STC8G1K08A的高效应用。 阅读详情

初看内联类

内联类非常的简单,您只需要在类的前面加上inline关键字就可以:

inline class WrappedInt(val value: Int)

内联类有一些或多或少明显的限制:需要在主构造函数中精确指定一个属性,如value所示。您不能在一个内联类中包装多个值。内联类中也禁止包含init块,并且不能具有带有幕后字段的属性。内联类可以具有简单的可计算属性,但是我们将在本文后面看到。

在运行时,将尽可能使用内联类的包装类型而不使用其包装。这类似于Java的框式类型,例如Integer或Boolean,只要编译器可以这样做,它们就会被表示为它们对应的原始类型。这正是Kotlin中内联类的一大卖点:内联类时,除非绝对必要,否则类本身不会在字节码中使用。内联类大大减少了运行时的空间开销。

运行时

在运行时,可以将内联类表示为包装类型和基础类型。如前一段所述,编译器更喜欢使用内联类的基础(包装)类型来尽可能地优化代码。这类似于int和Integer之间的装箱。但是,在某些情况下,编译器需要使用包装器本身,因此它将在编译期间生成:

public final class WrappedInt {
   private final int value;

   public final int getValue() { return this.value; }

   // $FF: synthetic method
   private WrappedInt(int value) { this.value = value; }

   public static int constructor_impl(int value) { return value; }

   // $FF: synthetic method
   @NotNull
   public static final WrappedInt box_impl(int v) { return new WrappedInt(v); }

   // $FF: synthetic method
   public final int unbox_impl() { return this.value; }

   //more Object related implementations
}

此代码段显示了内联类简化的Java字节码。除了一些显而易见的东西,例如value字段及其getter之外,构造函数是私有的,而新对象将通过Constructor_impl创建,该对象实际上并不使用包装器类型,而仅返回传入的基础类型。最后,您可以看到box_impl和unbox_impl函数,可能如您所期望的,它们的目的在于拆装箱的操作。现在,让我们看看在代码中如何使用内联类。

使用内联类

fun take(w: WrappedInt) {
    println(w.value)
}

fun main() {
    val inlined = WrappedInt(5)
    take(inlined)
}

在此代码段中,正在创建WrappedInt并将其传递给打印其包装值的函数。相应的Java字节码,如下所示:

public static final void take_hqTGqkw(int w) {
    System.out.println(w);
}

public static final void main() {
    int inlined = WrappedInt.constructor_impl(5);
    take_hqTGqkw(inlined);
}

在已编译的代码中,没有创建WrappedInt实例。尽管使用了静态的builder_impl函数,它只是返回一个int值,然后将其传递给take函数,该函数也对我们最初在源代码中拥有的内联类的类型一无所知。请注意,接受内联类参数的函数名称会用字节码中生成的哈希码扩展。这样,它们可以与接受基础类型作为参数的重载函数区分开:

fun take(w: WrappedInt) = println(w.value)
fun take(v: Int) = println(v.value)

为了使这两种take方法在JVM字节码中可用并避免签名冲突,编译器将第一个方法重命名为take-hqTGqkw之类的东西。注意,上面的示例确实显示了“ _”而不是“-”,因为Java不允许方法名称包含破折号,这也是为什么不能从Java调用接受内联类的方法的原因。

内联类的装箱

前面我们看到过,box_impl和unbox_impl函数是为内联类创建的,那么什么时候需要它们?Kotlin的文档引用了一条经验法则:

内联类在用作其他类型时会被装箱。

例如,当您将内联类用作通用类型或可为空的类型时,就会发生装箱:

inline class WrappedInt(val value: Int)

fun take(w: WrappedInt?) {
    if (w != null) println(w.value)
}

fun main() {
    take(WrappedInt(5))
}

在此代码中,我们修改了take函数以采用可为空的WrappedInt,并在参数不为null时显示基础类型。

public static final void take_G1XIRLQ(@Nullable WrappedInt w) {
    if (Intrinsics.areEqual(w, (Object)null) ^ true) {
        int var1 = w.unbox_impl();
        System.out.println(var1);
    }
}

public static final void main() {
    take_G1XIRLQ(WrappedInt.box_impl(WrappedInt.constructor_impl(5)));
}

在字节码中,take函数现在不再直接接受基础类型。它必须改为使用装箱类型。打印其内容时,将调用unbox_impl。在调用的地方,我们可以看到box_impl用于创建WrappedInt的装箱实例。

显然,我们希望尽可能避免装箱。请记住,内联类以及原始类型的特定用法通常都依赖于此技术,因此可能必须重新考虑是否该这么做。

使用案例

我们看到内联类具有巨大的优势:在最佳情况下,由于避免了额外的堆分配,它们可以大大减少运行时的开销。但是我们什么时候适合使用这种包装类型呢?

更好的区分类型

假如有一个身份验证方法API,如下所示:

fun auth(userName: String, password: String) { println("authenticating $userName.") }

在一个美好的世界中,每个人都会用用户名和密码来称呼它。但是,某些用户将以不同的方式调用此方法并不困难:

auth("12345", "user1")

由于这两个参数均为String类型,因此您可能会弄乱它们的顺序,当然,随着参数数量的增加,这种顺序的可能性更大。这些类型的包装类型可以帮助您减轻这种风险,因此内联类是一个很棒的工具:

inline class Password(val value: String)
inline class UserName(val value: String)

fun auth(userName: UserName, password: Password) { println("authenticating $userName.")}

fun main() {
    auth(UserName("user1"), Password("12345"))
    //does not compile due to type mismatch
    auth(Password("12345"), UserName("user1"))
}

参数列表变得越来越混乱,并且在调用方来看,编译器不允许出现不匹配的情况。先前描述的可能是使用内联类的最常见方案。它们为您提供了简单的类型安全的包装器,而无需引入其他堆分配。对于这些情况,应尽可能选择内联类。但是,内联类甚至可以更智能,这将在下一个用例中演示。

无需额外空间

让我们考虑一个采用数字字符串并将其解析为BigDecimal并同时调整其比例的方法:

/**
 * parses string number into BigDecimal with a scale of 2
 */
fun parseNumber(number: String): BigDecimal {
    return number.toBigDecimal().setScale(2, RoundingMode.HALF_UP)
}

fun main() {
    println(parseNumber("100.12212"))
}

该代码非常简单,可以很好地工作,但是一个要求可能是您需要以某种方式跟踪用于解析该数字的原始字符串。为了解决这个问题,您可能会创建一个包装类型,或者使用现有的Pair类从该函数返回一对值。这些方法虽然显然会分配额外的空间,但仍然是有效的,在特殊情况下应避免使用。内联类可以帮助您。我们已经注意到,内联类不能具有带有幕后字段的多个属性。但是,它们可以具有属性和函数形式的简单计算成员。我们可以为我们的用例创建一个内联类,该类包装原始的String并提供按需分析我们的值的方法或属性。对于用户而言,这看起来像是围绕两种类型的普通数据包装器,而在最佳情况下它不会增加任何运行时开销:

inline class ParsableNumber(val original: String) {
    val parsed: BigDecimal
        get() = original.toBigDecimal().setScale(2, RoundingMode.HALF_UP)
}

fun getParsableNumber(number: String): ParsableNumber {
    return ParsableNumber(number)
}

fun main() {
    val parsableNumber = getParsableNumber("100.12212")
    println(parsableNumber.parsed)
    println(parsableNumber.original)
}

如您所见,getParsableNumber方法返回我们内联类的实例,该实例提供原始(基础类型)和已分析(计算的已分析数量)两个属性。这是一个有趣的用例,值得再次在字节码级别上观察:

public final class ParsableNumber {
   @NotNull
   private final String original;

   @NotNull
   public final String getOriginal() { return this.original; }

   // $FF: synthetic method
   private ParsableNumber(@NotNull String original) {
      Intrinsics.checkParameterIsNotNull(original, "original");
      super();
      this.original = original;
   }

   @NotNull
   public static final BigDecimal getParsed_impl(String $this) {
      BigDecimal var10000 = (new BigDecimal($this)).setScale(2, RoundingMode.HALF_UP);
      Intrinsics.checkExpressionValueIsNotNull(var10000, "original.toBigDecimal().…(2, RoundingMode.HALF_UP)");
      return var10000;
   }

   @NotNull
   public static String constructor_impl(@NotNull String original) {
      Intrinsics.checkParameterIsNotNull(original, "original");
      return original;
   }

   // $FF: synthetic method
   @NotNull
   public static final ParsableNumber box_impl(@NotNull String v) {
      Intrinsics.checkParameterIsNotNull(v, "v");
      return new ParsableNumber(v);
   }

   // $FF: synthetic method
   @NotNull
   public final String unbox_impl() { return this.original; }

    //more Object related implementations
}

生成的包装类ParsableNumber几乎类似于前面显示的WrappedInt类。但是,一个重要的区别是getParsed_impl函数,该函数表示已解析的可计算属性。如您所见,该函数被实现为静态函数,该静态函数接受字符串并返回BigDecimal。那么在调用者代码中如何利用呢?

@NotNull
public static final String getParsableNumber(@NotNull String number) {
    Intrinsics.checkParameterIsNotNull(number, "number");
    return ParsableNumber.constructor_impl(number);
}

public static final void main() {
    String parsableNumber = getParsableNumber("100.12212");
    BigDecimal var1 = ParsableNumber.getParsed_impl(parsableNumber);
    System.out.println(var1);
    System.out.println(parsableNumber);
}

不出所料,getParsableNumber没有引用我们的包装类型。它只是返回String而不引入任何新类型。在主体中,我们看到静态的getParsed_impl用于将给定的String解析为BigDecimal。同样,不使用ParsableNumber。

缩小扩展函数的范围

扩展函数的一个常见问题是,如果在诸如String之类的常规类型上进行定义,它们可能会污染您的命名空间。例如,您可能需要一个扩展函数,将JSON字符串转换为相应的类型:

inline fun <reified T> String.asJson() = jacksonObjectMapper().readValue<T>(this)

要将给定的字符串转换为数据JsonData,您可以执行以下操作:

val jsonString = """{ "x":200, "y":300 }"""
val data: JsonData = jsonString.asJson()

但是,扩展功能也可用于表示其他数据的字符串,尽管可能没有多大意义:

"whatever".asJson<JsonData> //将会失败

由于字符串不包含有效的JSON数据,因此此代码将失败。我们该怎么做才能使上面显示的扩展名仅适用于某些字符串?不错,您需要的是内联类:

缩小扩展范围

inline class JsonString(val value: String)
inline fun <reified T> JsonString.asJson() = jacksonObjectMapper().readValue<T>(this.value)

当我们引入用于保存JSON数据的字符串的包装器并相应地将扩展名更改为使用JsonString接收器时,上述问题已得到解决。该扩展名将不再出现在任何任意String上,而是仅出现在我们有意识地包装在JsonString中的那些字符串上。

无符号类型

当查看版本1.3中添加到语言中的无符号整数类型时,内联类的另一个很好的案例就变得显而易见了,这也是一个实验功能:

public inline class UInt @PublishedApi internal constructor(@PublishedApi internal val data: Int) : Comparable<UInt>

如您所见,UInt类被定义为包装常规的带符号整数数据的无符号类。

总结

内联类是一个很棒的工具,可用于减少包装类型的堆分配,并帮助我们解决各种问题。但是,请注意,某些情况(例如将内联类用作可空类型)会进行装箱。由于内联类仍处于Alpha阶段,因此您必须接受未来代码会由于其行为的更改而在将来的版本中失效。这一点我们要记住。不过,我认为现在就开始使用它们是有合理的。

推荐阅读

最强总结 | Java-Kotlin双译手册,收藏必备

最强总结 | 带你快速搞定kotlin开发(下篇)

最强总结 | 带你快速搞定kotlin开发(中篇)

最强总结 | 带你快速搞定kotlin开发(上篇)

73da49b2aeef4b74a3a0130bff6b6798.jpeg

扫码关注我

一起感悟技术魅力

5b48129c0366d98f55b1e79de6c7275f.gif

点分享

f8af27e61c29fc77ecca55a2b574ec4e.gif

点收藏

16edd0950355f42e85ddd59f3eaa8d19.gif

点点赞

23c0d15c87be0b3f8e831b231b474b86.gif

点在看

姿态传感器/陀螺仪之ICM-42670-P应用原理图设计 ICM-42670-P采用LGA-14封装,尺寸为2.5x3x0.76毫米,工作电压范围为1.71V至3.6V,支持I3CSM、I2C和SPI串行通信接口。其设计目标是提供高精度、低功耗和小型化的解决方案,以满足消费类和工业应用的需求。ICM-42670-P是一款由TDK InvenSense推出的高性能六轴MEMS运动追踪传感器,集成了3轴陀螺仪和3轴加速度计,适用于多种应用场景,包括可穿戴设备、游戏控制器、无人机、AR/VR设备等。 阅读详情

相关推荐

基于多智能体协作的量化交易研究框架TradingAgents详解

量化交易系统通过算法模型分析市场数据,旨在实现自动化投资决策。其核心原理在于利用计算机强大的数据处理能力,结合统计学和机器学习方法,从历史数据中挖掘可重复的盈利模式。这一技术的价值在于能够克服人类情绪干扰,实现纪律性交易,并快速处理海量信息。在应用场景上,量化策略广泛应用于股票、期货、外汇等多个金融市场。本文聚焦的TradingAgents框架,创新性地引入了**多智能体协作**和**对抗性验证**机制,通过模拟真实投研团队的分工与辩论流程,构建了一个研究友好、决策过程可解释的量化交易研究平台,为探索大语言

weixin_36019375的博客 431

java绑定codesoft变量_零基础java

Java是印度尼西亚的英文简称 因咖啡二出名 1995年5月sun正式以Java来命名这种开发语言 1998年sun发布了全新的Java1.2版 也被分成了 j2se,j2ee,j2me三大平台,javase;全称java platfrom standar edition是java的技术核心主要用在桌面应用软件的开发javaee;全称 java platfrom enrerprise editio...

weixin_39942492的博客 579

OpenClaw 最强技能 self-improving-agent 详解:让 AI 从错误中自主学习

self-improving-agent 是 OpenClaw 生态中最受欢迎的技能插件,下载量突破 268k。它能让 AI 记住犯过的错误和解决方案,实现持续自我改进。本文深入讲解其工作原理、安装配置和实战案例。测试数据显示:部署流程时间从 15 分钟降到 2 分钟(87%↓),API 调试时间从 2 小时降到 20 分钟,数据库查询编写时间减少 90%。文章包含完整架构图、配置文件示例、3 个详细实战案例和性能测试数据,适合开发者、运维和数据分析师使用。

qq_38610923的博客 3633

kotlin 之几个常见的内联函数(一)

kotlin现在是Android 开发的主流语言,因为代码简洁,特别是一些内联函数的使用,跟java的比起来,代码量少却可以实现同样的功能。 接下来就来讲讲kotlin中常见的内联函数,他们在功能上,使用上都大同小异。分别是let函数、with函数、run函数、apply函数、also函数。一个一个来讲解。

怎么可以吃恐龙呢 968

从零构建个人知识库:Obsidian与Git实践打造可生长的第二大脑

在信息爆炸的时代,如何有效管理个人知识资产,构建一个可检索、可关联、可生长的个人知识库,成为提升学习效率和创造力的关键。其核心原理在于通过系统化的信息架构与工作流设计,将碎片化信息转化为结构化的知识网络。从技术价值看,这不仅是笔记方法的升级,更是个人知识管理(PKM)和思维模式的革新,能有效对抗信息过载与知识孤岛。实践中,以Obsidian为代表的本地Markdown笔记软件,结合双向链接和关系图谱功能,为知识网络的构建提供了强大支撑;而引入Git进行版本控制,则确保了知识资产的历史可追溯性与安全备份。这种

weixin_28836989的博客 301

ovs实现lb负载均衡

负载均衡器的实现原理是通过硬件或软件设备将客户端访问流量根据转发策略分发到多个服务器或设备上,以确保系统的负载均衡。二层负载均衡‌:使用虚拟MAC地址方式,根据OSI模型的二层进行负载均衡。‌四层负载均衡‌:基于IP+端口的负载均衡,主要分析IP层及TCP/UDP层,实现四层负载均衡。‌七层负载均衡‌:从应用层开始,根据虚拟的URL或IP、主机名接收请求,再转向相应的处理服务器。

bobi的博客 949

.net调用类时为什么有时会加上命名空间_绝对干货 | Kotlin内联类工作原理及使用案例,看完你会回来谢我的...

初看内联类内联类非常的简单,您只需要在类的前面加上inline关键字就可以:inlineclassWrappedInt(valvalue:Int)内联类有一些或多或少明显的限制:需要在主构造函数中精确指定一个属性,如value所示。您不能在一个内联类中包装多个值。内联类中也禁止包含init块,并且不能具有带有幕后字段的属性。内联类可以具有简单的可计算属性,但是我们将在本文后面看到...

weixin_33918202的博客 111

【深度学习新浪潮】算力行业的核心技术有哪些?

算力行业核心技术是芯片+互联+存储+调度+能效+软件的全栈协同:芯片提供算力、互联打通集群、存储保障数据、调度提升效率、能效支撑规模、软件释放算力。当前AI大模型推动算力从“单机”走向“万卡级超节点集群”,技术竞争从单一芯片升级为系统级、全栈化的综合能力。

专注:太空算力、AI infra、异构调度、大模型成本工程 338

android kotlin 开源,干货来袭,推荐几款开源的Kotlin的Android项目

废话不多说,直接上项目,别忘了star一波!1阅读精选Kotlin版https://github.com/LeeeYou/RsKotlin/阅读精选Kotlin版是一个由Kotlin开发的简易App,主要用于学习Kotlin语言以及和最新的框架结合使用。引入Kotlin1.1.0版开发引入Dagger2.4结合Kotlin引入Retrofit2.0结合Kotlin,抽取ServiceFactory...

weixin_35145307的博客 870

基于RK3568的YOLOv11模型端侧推理优化与部署实战指南

在AI边缘计算领域,瑞芯微RK3568芯片凭借其强大的NPU算力和丰富的接口资源,成为了众多开发者的首选平台。然而,瑞芯微官方文档虽然提供了YOLO11预训练模型的部署方案,但对于需要自定义数据集训练的开发者来说,从模型训练到板端部署的完整流程却缺乏详细指导。本文将带你走完从环境搭建、数据准备、模型训练到最终板端部署的完整技术路线,并分享实际开发中遇到的各种坑点和解决方案。让我们一起探索如何在RK3568平台上实现30FPS稳定推理的YOLO11目标检测应用!

m0_64661770的博客 115

国科大学习资料--图像处理(彭思龙、杨戈)--2020年期末考试题解析(学长整理分析)

在对20年卷子分析前,先看看19年卷子的解析(后面有20年的变化,由于从核心课调整到了普及课,20年的卷子相对简单,但是还是有很多细节) 解析:(字写的不好别嫌弃!!!!) 20年的卷子 第一题:和19年基本一致,但是加了高斯核计算费用,要算一个节省计算成本比率,所以去多看看PPT 第二题:和19年基本一致,加了证明两个高斯卷积仍然是高斯卷积,相当于19年题2和3结合 第三题:采样定理,和19年基本一致,但要注意加了证明 第四题:考了形态学提取图像边界 第五题:直方图,和19年一

无名何许人的博客 4364

博文干货|在 Kotlin 中使用 Apache Pulsar

关于 Apache PulsarApache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用计算与存储分离架...

Apache Pulsar 1751

手把手教你学Simulink实例:基于Simulink的锂电池管理系统(BMS)仿真

是确保锂电池安全、高效运行的关键组件。BMS 主要功能包括监控电池的状态(如电压、电流、温度)、估算荷电状态(State of Charge, SOC)、健康状态(State of Health, SOH),以及实现电池均衡和保护机制等。Simulink 提供了一个强大的仿真环境,可以用来设计、分析和验证锂电池管理系统的控制策略。常见的均衡方法包括被动均衡(通过电阻放电)和主动均衡(通过开关电容或变压器)。通过本教程,我们详细介绍了如何使用 Simulink 进行锂电池管理系统的仿真实例。

MHD0815的博客 538

Kotlin完成干货集中营APP

首先非常感谢http://gank.io/api/ 提供的API 使用kotlin完成干货集中营所有干货的APP 效果图: 项目地址 (欢迎Star)点击打开项目链接(https://github.com/MrGaoGang/KotlinGank) 效果图 此Gif图显示较快,可在apk目录中下载apk 很幸运和大家分享一个干货集中营Android APP,此APP使用kotlin语言...

mrgao的博客 655

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

干货丨Kotlin在Spring Boot中的应用

随着Kotlin在移动端开发的普及,它也逐步走入后端开发者的视野。Kotlin是JVM体系的语言,和Java有着良好的互操作性,上手较容易,且可以使用Java强大的生态,其还具有函数式编程的优点。另外,Spring Initializr提供了对Java、Kotlin语言的支持。 Kotlin是JetBrains公司开发的,目前流行的IntelliJ IDEA软件也是该公司开发的。IDEA对Kotlin支持较好,可以将Java代码转换为Kotlin代码。IDEA还支持Java、Kotlin混合编程...

博文视点(北京)官方博客 5328

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

干货 | 携程机票 App Kotlin Multiplatform 初探

作者简介陈琦,携程机票研发部无线研发总监,负责携程App机票业务的技术研发和管理工作。从2017年9月到2019年5月,经过一年半的努力,携程机票App团队完成 90% ...

携程技术中心 3292

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【腾讯Bugly干货分享】你为什么需要 Kotlin

曾经你有段时间研究 Intellij 的插件开发,企图编译 Intellij Idea Community Edition (ICE)的源码,结果发现有个奇怪的东西让你的代码无法编译。。什么鬼,kt 是什么玩意儿?

腾讯Bugly的专栏 5131

探秘Gank:优雅的Android与Kotlin干货神器

探秘Gank:优雅的Android与Kotlin干货神器 Gank干货集中营 app 安卓实现,基于 RxFlux 架构使用了 RxJava、Retrofit、Glide、Koin等项目地址:https://gitcode.com/gh_mirrors/gan/Gank 项目介绍 如果你是一位热衷于学习新技术的Android开发者,那么【Gank】绝对不容错过。这是一款专为Android和Kot...

gitblog_00025的博客 415

干货来袭,推荐几款开源的Kotlin的Android项目

Google IO大会,谷歌宣布,将Kotlin语言作为安卓开发的一级编程语言。刷新Android的各大论坛,朋友圈,微信群。是时候总结一波Kotlin的Android项目了! 废话不多说,直接上项目,别忘了star一波! 1 阅读精选Kotlin版 https://github.com/LeeeYou/RsKotlin/ 阅读精选Kotlin版是一个由K...

AI天才研究院 8759

Kotlin快速入门,全是干货没有废话

Kotlin 是一门现代但已成熟的编程语言,旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作,并提供了多种方式在多个平台间复用代码,以实现高效编程。

qq_45998763的博客 1551

Kotlin干货集中营

Kotlin 成为 Android 官方支持的编程语言。 笨鸟先飞,不要成为后知后觉的那一簇。来死狗吧! 1. kotlin的官方github地址 2. kotlin语言中文站 3. Kotlin 语言官方参考文档 中文版 4. 《Kotlin for android developers》中文版翻译 5. 张涛的开源实验室-《kotlin 一门强大的语言》 6. 大精-wing的地方

zrbcsdn的专栏 980

超干货详解:kotlin(4)-java转kotlin潜规则

作为一名即将求职的程序员,面对一个可能跟近些年非常不同的 2019 年,你的就业机会和风口会出现在哪里?在这种新环境下,工作应该选择大厂还是小公司?已有几年工作经验的老兵,又应该如何保持和提升自身竞争力,转被动为主动?就目前大环境来看,跳槽成功的难度比往年高很多。一个明显的感受:今年的面试,无论一面还是二面,都很考验Java程序员的技术功底。最近我整理了一份复习用的面试题及面试高频的考点题及技术点梳理成一份“Java经典面试问题(含答案解析).pdf和一份网上搜集的“Java程序员面试笔试真题库.pdf。

m0_60567881的博客 1145

干货拿走:深入解析Kotlin 泛型

0. 引子 Kotlin 100% 与 Java 兼容,所以抛开语言表面上面的种种特质之外,背后的语言逻辑或者说“灵魂”与 Java 总是想通的。本文只涉及 Kotlin Jvm,Kotlin Js、Kotlin Native 的具体实现可能有差异。 最近一段时间在网上发了一套 Kotlin 的入门视频,涵盖了基础语法、面向对象、高阶函数、DSL、协程等比较有特色的知识点,不过有朋友提出了疑问:这门课为什么不专门讲讲泛型、反射和注解呢? 我最早听到这个问题的时候,反应比较懵逼,因为我居然没有感觉到 K

粉丝交流群:569545109 670

Kotlin—练手App

Kotlin学习 最近刚好有点时间学习了一下kotlin,顺便做了一个app练手。 下载 GankPrac 感谢 干货集中营提供的数据 链接 代码

Ruomiz的博客 776

kotlin 实战之核心基础特性总结,满满的干货

var min: Int //标准写法 if (x > y) { min = y max = x } else { min = x max = y } //简写1,if 可以当作表达式 min = if (x > y) y else x //简写2,if 可以当作表达式,如果 if 后面是代码块则代码块中最后一行返回值返回 max = if (x > y) { println("x > y") x } e.

m0_61418377的博客 287
上一篇: Kotlin内联类-它是如何工作的以及我们该在什么场景使用它
下一篇: 通俗易懂的带你了解HTTPS的原理
IT烂笔头
博客等级 码龄15年 621粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值