Android Java语言转Kotlin语言学习指导实用攻略

Android Java语言转Kotlin语言学习指导实用攻略

一、前言

Kotlin七八年前也学习过但是很少用过,现在一看发现大部分知识都忘记了;

为啥要学习kotlin,因为系统开发的代码也有很多用到了kotlin代码:

比如:

复制代码
//系统应用 SystemUI 和 PackageInstaller
# frameworks/base/packages$ find . -name *.kt
./SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerKt.kt
./SystemUI/shared/src/com/android/systemui/shared/hardware/InputManager.kt
./SystemUI/shared/src/com/android/systemui/shared/hardware/InputDevice.kt
...
./PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallActionListener.kt
./PackageInstaller/src/com/android/packageinstaller/v2/ui/InstallLaunch.kt
./PackageInstaller/src/com/android/packageinstaller/v2/ui/UninstallLaunch.kt

//系统权限管理 permission
# frameworks/base/services$ find . -name *.kt
./permission/java/com/android/server/permission/access/permission/PermissionService.kt
./permission/java/com/android/server/permission/access/permission/Permission.kt
./permission/java/com/android/server/permission/access/permission/DevicePermissionPersistence.kt
...

上面是Android15 的源码代码,比之前Android13的代码kotlin代码多了好几倍;

Android13好像只有 SystemUI 部位代码是kotlin,后续系统代码估计会更多kotlin代码了!

所以说学习kotlin是非常有必要的。

kotlin有些代码看起来不难,比如下面一段代码:

复制代码
var name: String = "John"  // 可变变量
val age: Int = 30         // 不可变变量(类似 final)
if (age > 15) {
 Log.i(TAG, "成年人了")
}

大致能看懂,主要内容:

kotlin定义的变量关键字和Java不一样,使用var或者val;

kotlin后面不需要分号; ,if、else 那些逻辑写法是一样的;

但是复杂的kotlin就比较难懂了,比如下面一段代码:

复制代码
@Composable
fun Greeting(name: String) {
    Card(
        modifier = Modifier
            .padding(16.dp)
            .fillMaxWidth(),
        elevation = 8.dp
    ) {
        Column(
            modifier = Modifier.padding(16.dp)
        ) {
            Text(
                text = "Hello, $name!",
                fontSize = 24.sp,
                fontWeight = FontWeight.Bold
            )
            Spacer(modifier = Modifier.height(8.dp))
            Button(
                onClick = { /* 处理点击事件 */ },
                modifier = Modifier.align(Alignment.End)
            ) {
                Text("Click Me")
            }
        }
    }
}

上面是一段动态修改UI并且添加点击监听事件的代码;好像完全看不懂!写法也太简易了。

关键字:fun、Greeting、modifier、Modifier、Card、Column、Spacer 这些都是Java没有的;

如果没有深入学习过是不会懂的。之前学习基本用法好像没有学习过这些内容!

好吧,现在打算重新温习一下之前的知识学习看看kotlin其他知识吧。

本文主要让大家知道kotlin相关知识,和如何入门学习kotlin。

二、Kotlin 学习攻略:从入门到实战的系统指南

下面是kotlin各阶段主要相关知识:

第一阶段:基础语法与核心特性(1个月)

必学内容
  • 变量与类型系统val/var声明、类型推断、可空类型(String?)、类型安全转换(as?
  • 函数与 Lambda 表达式 :具名函数、匿名函数、高阶函数(如forEach)、函数引用(::println
  • 类与对象系统 :主构造函数、data class、单例模式(object关键字)、继承与接口实现
  • Kotlin 特色语法:
    • 空安全:?.(安全调用)、!!(非空断言)、?:( Elvis 操作符)
    • 扩展函数:为现有类添加功能(如String.toChineseDate()
    • 中缀表达式:1 to "one"
    • 解构声明:val (a, b) = pair
实践建议
  • 完成 Kotlin 官方入门教程
  • 用 Kotlin 重写 Java 基础程序(如计算器、文件操作)
  • 实现简单数据结构(链表、栈)理解泛型语法

第二阶段:Android 集成与进阶特性(2 个月)

核心技术栈
  • 协程(Coroutines):
    • 结构化并发(launch/async)、作用域管理(CoroutineScope
    • 异步流处理(flow/stateFlow
    • 结合 Retrofit 实现网络请求
  • Jetpack 组件集成:
    • ViewModel + LiveData + DataBinding
    • Room 数据库(Kotlin DSL 查询)
    • WorkManager(协程版 API)
  • Compose 声明式 UI:
    • 状态驱动 UI(mutableStateOf
    • 组合函数(@Composable
    • 动画与布局系统
进阶语法
  • 泛型编程:in/out型变、类型约束(where T : Comparable
  • 元编程:注解处理(KotlinPoet)、反射(KClass
  • 运算符重载:实现+[]等操作符

第三阶段:架构实践与性能优化(1个月)

工程实践
  • 架构模式:
    • MVVM(结合 Hilt 依赖注入)
    • Clean Architecture(领域模型设计)
    • Multi-Module 项目结构
  • 性能优化:
    • 内联函数(inline)与反编译分析
    • 密封类(sealed class)替代状态枚举
    • 协程上下文复用(Dispatchers优化)
跨平台开发
  • Kotlin Multiplatform(KMP)基础
  • 与 iOS/Swing/JS 的互操作

上面知识展示kotlin大概的知识,细节上的很多知识需要自己搜索学习,比如kotlin很多不同的关键字;

看完上面kotlin主要内容才知道,之前学习的kotlin都是第一阶段的知识;

还有很多kotlin相关的知识没有去学习,其实普通项目开发第一和第二阶段的知识已经够用了;

所以我目前也是打算温习第一阶段知识,学习一下第二阶段知识;

如果是大的kotlin项目会用到第三阶段的知识,小应用没必要写得太复杂。

上面是学习kotlin的大纲知识,只是一个大概的学习路线,更多更详细的学习资料需要另外寻找;

下面是学习kotlin的技巧。

三、Java转Kotlin学习技巧

现在从Android Java想要学习kotlin其实没有那么难,因为:

复制代码
1、现在新版本的Android Studio兼容Java代码和Kotlin代码;
2、Android Studio新建一个Kotlin项目代码,里面不同的类可以写Java代码也可以写Kotlin代码,
3、xml布局的控件kotlin和Java代码都可以find和控制;
4、Android原生提供的api接口,在Java和Kotlin是一样调用的,有些UI相关的api,Kotlin是做替换了关键字;
5、另外Java代码可以调用到Kotlin的类,Kotlin的类也可以调用Java的代码;
6、另外,Kotlin的代码复制到Java的类,会提示是否转换为Kotlin的代码;
7、最狠的一个:Java文件代码的类可以右键一键转换成Kotlin文件代码(虽然不一定完全准确)。

所以基于以上了解,学习kotlin就不会很吃力的,

只要你会写Java代码,那么学习kotlin第一和第二阶段的知识是没啥问题的;

kotlin学习只要难点无非就是关键字不认识,不懂什么意思;

看到上面第7点:Java代码文件可以转换成Kotlin代码文件,

你在Android Studio写一个Java可以运行的代码,转换成kotlin就可以了;

另外使用AI工具或者在线网址,也可以一键转换Java和kotin的代码,虽然有时候会不准确,稍微修改一点就可以用了。

上面只是学习kotlin的一些技巧,如果要学好kotlin还是需要多看多学多练。

三、其他

1、Java代码转换成Kotlin示例

Android Studio 创建一个kotlin项目,可以在里面写Java代码是没啥问题的,

并且Java调用Kolin对象,Kotlin调用Java对象都是没啥问题的。

两个语言在Android Studio中转换也是比较简单的,下面简单讲解一下:

(1)Java代码片段转换kotlin代码

下面框的地方是Java代码,复制到kt文件中,会提示是否自动转换成kotlin代码。

点击"Yes"转换后,会变成kotlin,如下图所示;

可以看到该有的逻辑都在,打印代码也在,代码变得简便一下了。

所以某个Java方法如果需要加在kotlin代码中,但是又不是很熟悉的情况,

就可以用Android Studio自动转换的方式,获取kotlin代码后加入。

注意:kotlin代码 复制到Java文件代码中,是没有提示的,会有很多报错。

(2)Java代码文件整个转换成kt文件

选择kt文件后,右键最下面就有" Convert Java File to Kotlin File "可以转换成kotlin文件的选择

上面本来是Java代码,点击转换后:

可以看类文件左边的小图标会发生变化,点击代码文件可以看到是kotlin的代码。

Android Studio中查看了一下只有Java转换Kotlin的工具和选项,

没看到Kotlin转换成Java的选项,网上搜到的都是假的;

其实不用慌,现在AI搜索工具非常发达,Kotlin转Java或者Java转Kotlin 都是没啥问题的。

2、Java和Kotlin 共存 demo代码实现

下面写了一个demo,两个一样的Activity界面,功能也是一样;

但是一个界面的代码使用的是Java代码,另外一个界面的逻辑使用的是Kotlin代码实现;

(1)效果
如下动图所示:

主要功能是:两个数相乘在后台计算后显示在右边;添加一个和上面数值相关的列表显示;

点击上面的标题,就会跳转到另外一个Activity。

(2)主要相关代码结构

如下图所示:

kotlin的项目就是要在gradle中配置一下支持kotlin,并且添加相关依赖就可以编译kotlin代码了;

上面把kt单独放在一个目录区分,主要是为了更好看,实际也可以不用区分,正常编译运行时没啥问题的。

可以看到 DebugLog.java工具类 在Java代码和kotlin代码都是可以调用的。

上面的Adapter和Item bean类也是可以共用的,这里只是为了多学习所以多写两个看看。

(3)主要代码

xml布局没啥好说的,一个 主界面是:LinearLayout布局,加上一个普通的item布局

Java相关代码:

①MainActivity.java

Java主界面代码

复制代码
package com.liwenzhi.webview;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.liwenzhi.webview.kt.MainKotlinActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tv_title;
    private TextView tv_result;
    private EditText et_num1;
    private EditText et_num2;
    private Button btn_calc;
    private RecyclerView rv_list;
    private JavaAdapter mAdapter;
    private List<JavaItem> mItemList;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DebugLog.info("");
        initView();
        initData();
        initEvent();
    }

    private void initView() {
        tv_title = findViewById(R.id.tv_title);
        tv_result = findViewById(R.id.tv_result);
        et_num1 = findViewById(R.id.et_num1);
        et_num2 = findViewById(R.id.et_num2);
        btn_calc = findViewById(R.id.btn_calc);
        rv_list = findViewById(R.id.rv_list);
    }

    private void initData() {
        tv_title.setText("Java Demo");
        rv_list.setLayoutManager(new LinearLayoutManager(this));
        mItemList = new ArrayList<>();
        mAdapter = new JavaAdapter(mItemList);
        rv_list.setAdapter(mAdapter);
    }

    private void initEvent() {
        tv_title.setOnClickListener(this);
        btn_calc.setOnClickListener(this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        DebugLog.debug("");
    }

    @Override
    public void onClick(View v) {
        DebugLog.info("view = " + v.getId());
        switch (v.getId()) {
            case R.id.tv_title:
                startActivity(new Intent(this, MainKotlinActivity.class));
                finish();
                break;
            case R.id.btn_calc:
                getResult();
                generateData();
                break;
        }
    }


    private void getResult() {
        // 使用线程池和回调
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                // 后台任务
                final String result = fetchData();

                // 回到主线程
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tv_result.setText(result);
                    }
                });
            }
        });
    }


    //数值相乘求结果
    private String fetchData() {
        String num1 = et_num1.getText().toString();
        String num2 = et_num2.getText().toString();
        String result = "";
        try {
            result = "" + Integer.parseInt(num1) * Integer.parseInt(num2);
        } catch (NumberFormatException e) {
            DebugLog.error("NumberFormatException num1 = " + num1 + ", num2 = " + num2);
            return "error";
        }

        DebugLog.debug("result = " + result);
        return result;
    }

    //生成列表数据
    private void generateData() {
        mItemList.clear();
        int intNum1 = 0;
        int intNum2 = 0;
        String num1 = et_num1.getText().toString();
        String num2 = et_num2.getText().toString();
        try {
            intNum1 = Integer.parseInt(num1);
            intNum2 = Integer.parseInt(num2);
        } catch (NumberFormatException e) {
            DebugLog.error("NumberFormatException num1 = " + num1 + ", num2 = " + num2);
        }

        for (int i = 0; i < 10; i++) {
            mItemList.add(new JavaItem(intNum1 + i, intNum2 + i));
        }
        mAdapter.notifyDataSetChanged();
    }

}

上面的代码都是比较简单易懂的,除了写了一个线程池的写法比较少用到。

② JavaAdapter.java

RecyclerView 的适配器的代码

复制代码
package com.liwenzhi.webview;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class JavaAdapter extends RecyclerView.Adapter<JavaAdapter.MyViewHolder> {
    private List<JavaItem> itemList;

    public JavaAdapter(List<JavaItem> itemList) {
        this.itemList = itemList;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_layout, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        JavaItem item = itemList.get(position);
        holder.tv_info.setText("" + item.getInfo());
        holder.tv_result.setText("" + item.getResult());
    }

    @Override
    public int getItemCount() {
        return itemList.size();
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView tv_info;
        public TextView tv_result;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tv_info = itemView.findViewById(R.id.tv_info);
            tv_result = itemView.findViewById(R.id.tv_result);
        }
    }
}
③ JavaItem.java

普通的item代码

复制代码
package com.liwenzhi.webview;

public class JavaItem {

    private int num1 = 0;
    private int num2 = 0;

    JavaItem(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

    public String getInfo() {
        return num1 + " * " + num2 + " = ";
    }

    public int getResult() {
        return num1 * num2;
    }
}

kotlin代码:

Kotlin的代码文件后缀不再是java而是Kotlin的简称kt

④ MainKotlinActivity.kt

kotlin写的界面代码

复制代码
package com.liwenzhi.webview.kt

import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.liwenzhi.webview.DebugLog
import com.liwenzhi.webview.R
import java.util.concurrent.Executors


class MainKotlinActivity : AppCompatActivity(), View.OnClickListener {

    private lateinit var tv_title: TextView
    private var tv_result: TextView? = null
    private var et_num1: EditText? = null
    private var et_num2: EditText? = null
    private var btn_calc: Button? = null
    private var rv_list: RecyclerView? = null
    private var mAdapter: KotlinAdapter? = null
    private var mItemList: ArrayList<KotlinItem>? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_main)
        initView()
        initData()
        initEvent();
    }

    override fun onResume() {
        super.onResume()
        DebugLog.debug("")
    }

    private fun initView() {
        tv_title = findViewById(R.id.tv_title)
        tv_result = findViewById(R.id.tv_result)
        et_num1 = findViewById(R.id.et_num1)
        et_num2 = findViewById(R.id.et_num2)
        btn_calc = findViewById(R.id.btn_calc)
        rv_list = findViewById(R.id.rv_list)
    }

    private fun initData() {
        tv_title?.text = "Kt demo"
        mItemList = ArrayList() //kotlin 没有new关键字
        mAdapter = KotlinAdapter(mItemList as ArrayList<KotlinItem>) // 不加 as ArrayList<KotlinItem> 会报错!因为Kotlin 没有泛型数组,只有泛型列表
        rv_list?.layoutManager = LinearLayoutManager(this) // 布局管理器绑定到列表,必须加,不然不显示
        rv_list?.adapter = mAdapter // 适配器绑定到列表,这种写法就很怪!因为Kotlin 没有setAdapter方法,只有adapter属性
    }

    private fun initEvent() {
        tv_title?.setOnClickListener(this)
        btn_calc?.setOnClickListener(this)
    }

    override fun onClick(v: View) {
        DebugLog.info("view = " + v.id)
        when (v.id) {
            R.id.tv_title -> {
                DebugLog.debug("点击了标题")
                startActivity(Intent(this, MainKotlinActivity::class.java))
                finish()
            }

            R.id.btn_calc -> getResult()
        }
    }

    private fun getResult() {
        generateData() // 生成列表数据,并更新列表
        // 使用线程池和回调
        Executors.newSingleThreadExecutor().execute { // 后台任务
            val result = fetchData()
            // 回到主线程
            runOnUiThread { tv_result!!.text = result }
        }
    }

	//数值相乘求结果
    private fun fetchData(): String {
        val num1 = et_num1?.text.toString()

        val num2 = et_num2?.text.toString()
        var result = ""
        try {
            result = "" + num1.toInt() * num2.toInt()
        } catch (e: NumberFormatException) {
            DebugLog.error("NumberFormatException num1 = $num1, num2 = $num2")
            return "error"
        }
        DebugLog.debug("result = $result") //可以写成Java一样,Kotlin也可以写成 这种类似C的写法
        return result
    }


    //生成列表数据
    private fun generateData() {
        mItemList?.clear()
        var intNum1 = 0
        var intNum2 = 0
        val num1 = et_num1!!.text.toString()
        val num2 = et_num2!!.text.toString()
        DebugLog.debug("num1 = $num1, num2 = $num2")
        try {
            intNum1 = num1.toInt()
            intNum2 = num2.toInt()
        } catch (e: java.lang.NumberFormatException) {
            DebugLog.error("NumberFormatException num1 = $num1, num2 = $num2")
        }

        for (i in 0..9) {
            mItemList?.add(KotlinItem(intNum1 + i, intNum2 + i))
        }

        DebugLog.debug("mItemList size = " + mItemList?.size + " , " + mAdapter)
        mAdapter?.notifyDataSetChanged()
    }

}

上面的代码还是比较简单明了的,逻辑上可以对比Java代码。

上面的代码对比Java主要区别:

复制代码
1、继承和实现接口不用区分,不用关键字,使用逗号,区分分隔;
2、变量定义的关键字不同,Kotlin只用var和val;
3、kotlin没有void,只能用fun;
4、kotlin没有new,直接省略就行;
5、kotlin没有switch只有when;
6、kotlin对象基本都要添加问号?或者两个说明号::进行判空;
7、线程池和普通回调使用可以省略很多关键字;
8、RecyclerView 的赋值Adapter不能用set,用变量赋值就行。
⑤ KotlinAdapter.kt

kotlin写的 RecyclerView的适配器的代码

复制代码
package com.liwenzhi.webview.kt

import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.liwenzhi.webview.R

class KotlinAdapter(private var itemList: List<KotlinItem>) :
    RecyclerView.Adapter<KotlinAdapter.MyViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
//        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
        val view = View.inflate(parent.context, R.layout.item_layout, null)
        return MyViewHolder(view)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val item = itemList[position]
        holder.tv_info.text = "" + item.info
        holder.tv_result.text = "" + item.result
    }

    override fun getItemCount(): Int =  itemList.size

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        var tv_info: TextView = itemView.findViewById(R.id.tv_info)
        var tv_result: TextView = itemView.findViewById(R.id.tv_result)
    }
}

上面可以看到kotlin的构造方法可以直接声明在类定义的地方。

⑥ KotlinItem.kt

kotlin写的item bean类代码

复制代码
package com.liwenzhi.webview.kt

class KotlinItem internal constructor(num1: Int, num2: Int) {
    private var num1 = 0
    private var num2 = 0

    init {
        this.num1 = num1
        this.num2 = num2
    }

    val info: String
        get() = "$num1 * $num2 = "

    val result: Int
        get() = num1 * num2
}

为啥这里的构造方法需要添加关键字:internal constructor,上面Adapter不需要?

其实也可以不使用这两个关键字也可以的,这里作用只是为了限制使用范围;

internal 类似 protected 的作用,但是作用范围又大一些,

当构造函数需要对库内部可见,但对外部隐藏时使用。

比如使用了internal constructor关键字,变成的jar包,其他应用导入后不能new这个构造方法。

Kotlin 提供四种访问修饰符:publicprivateprotectedinternal

这个demo也是学习kotlin的一个简单演示,更多的还需要自己去实践磨练。

可以把写过的Android demo 使用kotlin写一遍,基本就能掌握kotlin第一阶段的内容了;

3、Android Kotlin 用法对比Java使用小结

本文介绍一些入门级的Kotlin简单用法,可以对Kotlin的代码使用有个大致了解。

以下是 Kotlin 与 Java 在 Android 开发中核心差异的详细对比:

https://blog.csdn.net/wenzhi20102321/article/details/148797427

PS: 命运不会辜负认真准备的人呀

相关推荐
一ge科研小菜鸡12 分钟前
编程语言的演化与选择:技术浪潮中的理性决策
java·c语言·python
我崽不熬夜30 分钟前
为什么你该立即学习 Java 的 Lambda 表达式?
java·后端·java ee
wsdchong之小马过河32 分钟前
2025虚幻引擎文件与文件夹命名规律
java·数据库·虚幻
幸运的大号暖贴37 分钟前
单点登录进阶:基于芋道(yudao)授权码模式的单点登录流程、代码实现与安全设计
java·安全
小白的代码日记1 小时前
IDEA 中 Tomcat 部署 Java Web 项目(Maven 多模块 & 非 Maven 通用版)(linux+windows)
java·tomcat·intellij-idea
coder_zh_1 小时前
Spring Boot自动配置原理
java·spring boot·spring
云博客-资源宝1 小时前
Android Manifest 权限描述大全
android·开发语言·php
xzkyd outpaper1 小时前
Android DataBinding 与 MVVM
android·计算机八股
zzq19962 小时前
Android 14.0 framework默认将三按钮的导航栏修改为手势导航。
android
晴空月明2 小时前
线程安全集合选择深度解析
java