Kotlin和Java区别
哈哈哈,前段时间,面试的时候,突然问到我Kotlin和Java的区别,一下子把我问懵逼了,确实没遇到问这个的,想了下,说了下Kotlin的编译时空检查机制,代码更简洁,很多封装好的API可以直接调用,Kotlin有Jetpack全家桶,有协程,有lateinit和by lazy懒加载机制等等,后面着重问我协程去了,但是我知道我也有很多没有答上。
今天自己做个总结:
1. 语法简洁性
🔹 Kotlin 代码通常比 Java 更简洁,减少了模板代码(boilerplate)。
🔸 Java 示例(获取 List 的大小并遍历):
List<String> list = Arrays.asList("A", "B", "C");
for (String item : list) {System.out.println(item);
}
Kotlin
val list = listOf("A", "B", "C")
list.forEach { println(it) }
2. Null 安全
🔹 Java 中 NullPointerException (NPE) 是常见错误:
String name = null;
System.out.println(name.length()); // 运行时崩溃:NullPointerException
🔹 Kotlin 通过可空类型和安全调用避免 NPE:
var name: String? = null
println(name?.length) // 安全调用,避免 NPE
?允许null值?.安全访问,避免 NPE!!强制非空,可能引发异常,尽量少用。
3. 数据类 (Data Class)
🔹 Java 需要大量代码来定义 POJO(数据类):
public class User {private String name;private int age;public User(String name, int age) { this.name = name; this.age = age; }public String getName() { return name; }public int getAge() { return age; }public void setName(String name) { this.name = name; }public void setAge(int age) { this.age = age; }@Overridepublic String toString() { return "User{name='" + name + "', age=" + age + "}"; }
}
🔹 Kotlin 只需一行代码:
data class User(val name: String, val age: Int)
- 自动生成
getter/setter、toString()、equals()和hashCode()。
data class的详细介绍和区别:Serializable,Parcelable和data class的区别_data class parcelable-CSDN博客文章浏览阅读992次,点赞24次,收藏26次。序列化是将对象的状态(属性数据)转换为字节流或其他可存储或传输的格式的过程。主要作用存储:将对象保存到文件或数据库中。传输:在网络中传输对象,比如在客户端与服务器之间传递数据。缓存:将对象转化为可恢复的格式,便于后续恢复使用。序列化后7. 什么是反序列化(Deserialization)?反序列化是将序列化后的字节流(或存储格式)重新转换回原始对象的过程。主要作用从存储或传输的格式中重建对象。恢复数据到应用中,便于程序继续使用。8.序列化与反序列化的用途网络传输。_data class parcelablehttps://blog.csdn.net/LoveFHM/article/details/143875848?spm=1001.2014.3001.5502
4. 扩展函数 (Extension Functions)
🔹 Java 需要创建工具类来扩展已有类的功能
public class StringUtils {public static String capitalize(String str) {return str.substring(0, 1).toUpperCase() + str.substring(1);}
}
String result = StringUtils.capitalize("hello");
🔹 Kotlin 直接扩展类的方法
fun String.capitalizeFirst(): String = this.replaceFirstChar { it.uppercaseChar() }
val result = "hello".capitalizeFirst()
5. 函数式编程
Kotlin 支持 高阶函数 和 Lambda 表达式,让代码更优雅。
🔹 Java 的匿名内部类:
button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {System.out.println("Clicked");}
});
🔹 Kotlin 的 Lambda 表达式:
button.setOnClickListener { println("Clicked") }
6. 协程 vs. Java 线程
🔹 Java 使用线程管理并发,代码较复杂:
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("线程运行中...");}
}).start();
🔹 Kotlin 协程更高效,且不会阻塞线程
GlobalScope.launch {println("协程运行中...")
}
- 协程比 Java 线程更轻量,可以高效处理并发任务。管理起来也很轻松,可以和生命周期绑定
Kotlin 协程(一)协程的定义及基础使用_kotlin 协程使用-CSDN博客
7. Smart Cast(智能类型转换)
🔹 Java 需要显式类型转换
Object obj = "Hello";
if (obj instanceof String) {String str = (String) obj; // 需要手动转换
}
🔹 Kotlin 自动类型转换
val obj: Any = "Hello"
if (obj is String) {println(obj.length) // Kotlin 自动转换,无需 `(String) obj`
}
-
智能类型推断:Kotlin 可以自动推断变量类型,无需显式声明,如
val name = "Lee"而不需要String name = "Lee";。
8. when 取代 switch
🔹 Java switch-case 语法繁琐
🔹 Kotlin when 语法更简洁,when 更直观,支持范围判断和表达式返回值。
9. 类默认 final
-
Java 类默认是
open的,可以继承,除非加final -
Kotlin 类默认
final,必须显式open允许继承
10.总结对比表
| 特性 | Java | Kotlin |
|---|---|---|
| 语法 | 冗长 | 简洁 |
| Null 安全 | 可能导致 NPE | 避免 NPE |
| 数据类 | 需要手写 getter/setter | data class 自动生成 |
| 扩展函数 | 需要工具类 | 直接扩展 |
| 高阶函数 | 需要匿名类 | 直接支持 Lambda |
| 并发 | 线程(较重) | 协程(轻量) |
| 类型转换 | 需手动转换 | 自动 Smart Cast |
| switch 语法 | switch-case | when |
| 类默认行为 | 默认可继承 | 默认 final |
其他的:
11. Kotlin的懒加载
在 Kotlin 中,懒加载(Lazy Initialization)主要有两种方式:
lazy(适用于 val 只读变量)lateinit(适用于 var 可变变量)
Kotlin by lazy和lateinit的使用及区别_kotlin by lazy 与lateinit-CSDN博客
12.单例模式
传统的懒汉式(lazy + @Volatile + synchronized)
class Singleton private constructor() {companion object {@Volatileprivate var instance: Singleton? = nullfun getInstance(): Singleton {return instance ?: synchronized(this) {//第一次空检查instance ?: Singleton().also { instance = it }//第二次空检查}}}
}
这里的双重检查:
-
第一次检查 (
instance ?:)- 避免不必要的同步开销。
- 如果已经初始化,直接返回,避免进入
synchronized代码块,提高性能。
-
同步代码块内部的第二次检查 (
instance ?:)- 由于多个线程可能同时通过第一次检查进入
synchronized,所以 需要再次检查instance是否为null,防止重复创建实例。
- 由于多个线程可能同时通过第一次检查进入
为什么要用 @Volatile?
-
@Volatile防止指令重排序(保证可见性)。 -
如果不加
@Volatile,可能会发生 部分初始化(对象创建未完成,别的线程就拿到不完整的实例)。 -
避免可能的 NullPointerException(NPE)。
lazy懒加载
class Singleton private constructor() {companion object {val instance: Singleton by lazy { Singleton() }}
}
- 线程安全(
lazy默认是LazyThreadSafetyMode.SYNCHRONIZED)。 - 更简洁,不需要
synchronized和@Volatile。
最简单的单例
object Singleton {fun doSomething() {println("Hello from Singleton!")}
}
-
线程安全,在 Kotlin 中,
object关键字天然是线程安全的,因为它的初始化由 JVM 类加载机制(Class Loading Mechanism) 保证,由于 JVM 类加载过程是线程安全的,所以object也是线程安全的! -
写法简单
-
类加载时就初始化(饿汉式)
🔹 双重检查锁的 Java 代码
public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) { // 第一次检查(避免不必要的同步)synchronized (Singleton.class) { // 线程同步if (instance == null) { // 第二次检查(确保只创建一次)instance = new Singleton();}}}return instance;}
}
相关文章:
Kotlin和Java区别
哈哈哈,前段时间,面试的时候,突然问到我Kotlin和Java的区别,一下子把我问懵逼了,确实没遇到问这个的,想了下,说了下Kotlin的编译时空检查机制,代码更简洁,很多封装好的AP…...
Taro 面试题
基础概念 1. Taro 是什么?它的核心特点有哪些? Taro 是京东开源的 多端统一开发框架,基于 React 语法,可编译到 微信小程序、H5、React Native 等多个端。 核心特点: 多端适配:一套代码运行多个端支持 …...
Java部署在window启动报unable tocreate tempdir
在Windows系统中,Java应用在运行时会试图在默认的临时目录中创建文件。该临时目录通常由系统环境变量TEMP或TMP指定。如果这些变量设置不正确、指向一个无效的路径,或者操作系统的权限不足,就会导致“Unable to create tempdir”错误。 解决…...
基于deepseek和开放题库,构建专业大模型微调在线答题系统
为什么要进行大模型微调 大模型微调是将预训练模型适配到特定任务或领域的关键技术,正常情况下大模型通过海量通用数据训练获得广泛知识,但其参数和表征空间面向通用场景,难以直接适配垂直领域或复杂任务。例如在通用医疗问答模型在具体病症诊…...
ios 小组件和数据共享
创建主工程就不必讲了 1 创建小组件 创建子工程 [new Target ] 选择 [ Widger Extension] 小组件入口是WidgetBundle文件,可以进行多个小组件的调试 TestWidget2文件是主要操作,小组件使用swiftUI布局,使用 AppIntent进行事件处理ÿ…...
LVTTL(Low Voltage Transistor-Transistor Logic)电平详解
一、LVTTL电平的定义与核心特性 LVTTL(低压晶体管-晶体管逻辑)是传统TTL(5V)的低电压版本,工作电压通常为3.3V,旨在降低功耗并适配现代低电压集成电路,同时保持与TTL的逻辑兼容性。其核心特点如…...
element tree树形结构默认展开全部
背景: el-tree树形结构,默认展开全部,使用属性default-expand-all【是否默认展开所有节点】;默认展开一级,设置default-expanded-keys【默认展开的节点的 key 的数组】属性值为数组。 因为我这里的数据第一级是四川【省…...
统计登录系统10秒内连续登录失败超过3次的用户
为防止暴力破解用户账号的行为,在输入账号和密码时一般都会限制用户尝试密码输出错误的次数,如果用户多次输错密码后,将在一段时间内锁定账号,常见的有银行类APP、个税App等应用,如下是用户账号密码输入错误的提示图&a…...
音视频软件工程师面试题
一、基础知识 编解码相关 H.264 和 H.265(HEVC)的主要区别是什么?视频编解码的基本流程是什么?关键技术有哪些?音频编解码(如 AAC、MP3、Opus)的区别和应用场景?什么是 B 帧、P 帧、I 帧?它们的作用是什么? 流媒体协议RTMP、HTTP-FLV、HLS、WebRTC 的区别和应用场景…...
架构师面试(十四):注册中心设计
问题 大家或多或少都接触过【注册中心】,对注册中心的基本功能,如:服务注册、服务发现、健康检查和变更通知 ,肯定是耳熟能详的;那么大家对注册中心的架构设计是否了解呢? 如果让你负责设计一个分布式的注…...
ctf-web: php原生类利用 -- GHCTF Popppppp
源代码 <?php error_reporting(0); class CherryBlossom { public $fruit1; public $fruit2; public function __construct($a) {$this->fruit1 $a; } function __destruct() { echo $this->fruit1; } public function __toString() { $newFunc …...
「Unity3D」UGUI将元素固定在,距离屏幕边缘的某个比例,以及保持元素自身比例
在不同分辨率的屏幕下,UI元素按照自身像素大小,会发生位置与比例的变化,本文仅利用锚点(Anchors)使用,来实现UI元素,固定在某个比例距离的屏幕边缘。 首先,将元素的锚点设置为中心&…...
nextjs15简要介绍以及配置eslint和prettier
目录 一、Next.js 何时使用服务器端渲染(SSR)?何时使用静态生成(SSG)? 1、服务器端渲染(SSR - getServerSideProps) 2、 静态生成(SSG - getStaticProps) …...
存储过程和自定义函数在银行信贷业务中的应用(oracle)
数据校验和清洗 例如,检查客户的年龄是否在合理范围内,贷款金额是否符合规定的上下限等。 对于不符合规则的数据,可以进行清洗和修正。比如,将空值替换为默认值,或者对错误的数据进行纠正。 CREATE OR REPLACE PROC…...
基于Ollama平台部署的Qwen大模型实现聊天机器人
文章目录 基于Ollama平台部署的Qwen大模型实现聊天机器人1 概述2 技术栈2.1 开发技术2.2 环境 3 技术架构4 实现步骤4.1 环境搭建4.1.1 WSL配置及Ubuntu安装4.1.2 Ollama安装及模型部署 4.2 模块安装4.2.1 安装Streamlit 1.42.24.2.2 安装requests 2.32.34.2.3 安装ollama 0.4.…...
在 JDK 1.8 的 ConcurrentHashMap 中,为什么存在两种插入方式?
在 JDK 1.8 的 ConcurrentHashMap 中,之所以对“容器为空”和“计算位置为空”采取不同的处理方式,主要是因为 并发场景下的性能优化和并发安全保证。我们可以分开来看这两种情况: 1. 容器为空时,使用 volatile CAS 初始化 原因…...
如何让powershell的界面变成全屏显示?
刚打开powershell,原来的样子: 全屏:可以按一下键盘上的alt enter 键,效果:...
语音识别踩坑记录
本来想在原来的语音识别的基础上增加本地扩展本地词典, 采用的语音识别是Vosk识别器,模型是 vosk-model-small-cn-0.22 // 初始化Vosk识别器 if (recognizer null) {using (Model model new Model(modelPath)){string grammar "{""…...
图片查看器:用PyQt5实现本地图片预览工具
通过python代码,基于PyQt5实现本地图片预览查看工具。 我们对窗口进行了圆角设计,图片的翻页按钮半透明处理,当鼠标移动至按钮上的动画效果,当选择某一张图片,进行左右翻页则轮播同目录所有支持的图片格式。 import …...
Deepin通过二进制方式升级部署高版本 Docker
一、背景: 在Deepin系统中通过二进制方式升级部署高版本 Docker,下面将详细介绍二进制方式升级部署高版本 Docker 的具体步骤。 二、操作步骤 1.根据需求下载二进制文件,下载地址如下: https://mirrors.tuna.tsinghua.e…...
JSON·学习笔记
“误报。我的安全阀一切正常。” “我们继续,今天我想解释一下什么是JSON。” “是啊,这个词我听过很多次了,什么意思?” “随着网络的发展,带有 JavaScript 的 HTML 页面开始主动与服务器通信并从服务器下载数据。为…...
别再犯这些错误!英文邮件写作中的常见误区与正确写法
英文邮件写作进阶指南:避开9个致命错误,展现专业沟通力 在跨国商务沟通中,一封得体的英文邮件就像精心设计的数字名片。我曾见证过一位工程师因为邮件中一个称呼错误,导致价值200万美元的合同谈判陷入僵局;也见过实习生…...
基于关键链方法的遗传算法求解项目调度问题
一、问题背景与核心思想 项目调度问题(Project Scheduling Problem, PSP)是在满足活动逻辑关系(紧前约束)和资源约束(如人力、设备)的前提下,确定各活动开始/结束时间,以最小化项目工…...
从零到一:Vision Pro工业视觉软件安装与配置实战指南
1. Vision Pro工业视觉软件入门指南 第一次接触Vision Pro的朋友可能会被这个强大的工业视觉软件震撼到。作为康耐视的拳头产品,它在汽车制造、电子检测、包装印刷等行业应用广泛。我刚开始用的时候也是一头雾水,但跟着正确的步骤走,其实安装…...
s2-pro效果展示:多说话人语音合成(同一模型切换不同音色)
s2-pro效果展示:多说话人语音合成(同一模型切换不同音色) 1. 专业级语音合成效果展示 s2-pro作为Fish Audio开源的专业级语音合成模型,其最惊艳的能力在于同一模型支持多种音色切换。通过上传不同的参考音频,模型可以…...
从VGG到ResNet:为什么说‘残差块’是深度学习模型‘卷’层数的救命稻草?
从VGG到ResNet:残差连接如何重塑深度神经网络的设计哲学 2014年ImageNet竞赛上,VGGNet凭借其规整的3x3卷积堆叠结构一举夺魁,将图像识别准确率提升到新高度。正当整个计算机视觉领域沉浸在"更深就一定更好"的乐观情绪中时ÿ…...
Ubuntu16.04服务器上从零部署LaneNet车道线检测:Tusimple数据集处理全流程避坑指南
Ubuntu 16.04服务器部署LaneNet车道线检测全流程实战 在自动驾驶和智能交通系统中,车道线检测是一项基础而关键的技术。本文将详细介绍如何在Ubuntu 16.04服务器环境下,从零开始部署LaneNet车道线检测模型,并处理Tusimple数据集的全流程。不同…...
告别复杂配置:SDXL 1.0电影级绘图工坊开箱即用体验
告别复杂配置:SDXL 1.0电影级绘图工坊开箱即用体验 1. 为什么选择SDXL 1.0电影级绘图工坊 在AI绘图领域,Stable Diffusion XL(SDXL)1.0代表了当前最先进的文本到图像生成技术。然而,对于大多数非技术背景的创作者来说…...
RWKV7-1.5B-g1a保姆级部署教程:离线加载+免外网依赖,中小企业AI落地首选
RWKV7-1.5B-g1a保姆级部署教程:离线加载免外网依赖,中小企业AI落地首选 1. 模型简介 rwkv7-1.5B-g1a 是基于新一代 RWKV-7 架构的多语言文本生成模型,专为中小企业AI落地场景优化设计。这个1.5B参数的轻量级模型在保持高质量生成能力的同时…...
ROS2 Humble下,如何用一份Xacro文件同时搞定MoveIt2配置与Gazebo仿真(附完整Launch文件)
ROS2 Humble统一建模实战:Xacro文件在MoveIt2与Gazebo中的协同设计 当机械臂的URDF文件需要同时满足MoveIt2的运动规划需求和Gazebo的物理仿真要求时,开发者往往陷入两难境地。传统方案需要维护两份模型文件——一份精简版用于MoveIt,另一份增…...
