全民 Kotlin:Java 我们不一样

2,276 阅读8分钟

本文章已授权鸿洋微信公众号转载

随着 Kotlin 越来越火爆,学习 Kotlin 已经成为我们必经之路

多余的话就不说了,代码是最好的老师

目录

  • 集成 Kotlin

  • new 关键字

  • this 关键字

  • class 关键字

  • extends 关键字

  • volatile 关键字

  • synchronized 关键字

  • final 关键字

  • 变量

  • 静态常量

  • 定义方法

  • 重载方法

  • 基本数据类型

  • 比较类型

  • 比较对象

  • 转换符

  • 数组

  • 循环

  • 角标循环

  • 高级循环

  • 判断器

  • 构造函数

  • 创建类

  • 私有化 set 方法

  • 私有化 get 方法

  • 枚举

  • 接口

  • 匿名内部类

  • 内部类

  • 内部类访问外部类同名变量

  • 抽象类

  • 静态变量和方法

  • 可变参数

  • 泛型

  • 构造代码块

  • 静态代码块

  • 方法代码块

  • 三元运算符

  • 权限修饰符

  • 抑制代码警告

  • 注解处理器

集成 Kotlin

  • 需要先在项目 app 模块下的 build.gradle 文件中加入配置
apply plugin: 'kotlin-android'

android {

    kotlinOptions {
        jvmTarget = '1.8'
    }
}
  • 然后在项目根目录下的 build.gradle 文件中加入 Kotlin 插件配置
buildscript {

    dependencies {
        // Kotlin 插件:https://plugins.jetbrains.com/plugin/6954-kotlin
        // noinspection GradleDependency
        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31'
    }
}
  • 需要注意的是,这里以 Android Studio 4.2 为例,集成的是 kotlin-gradle-plugin:1.5.31 版本是没有问题的,这个 Kotlin 插件使用的版本和当前 Android Studio 版本相关,如果遇到集成失败的,需要自行修改到合适的版本。

new 关键字

  • Java 的写法
Intent intent = new Intent();
  • Kotlin 的写法
var intent = Intent()

this 关键字

  • Java 的写法
MainActivity.this
  • Kotlin 的写法
this@MainActivity

class 关键字

  • Java 的写法
MainActivity.class
  • Kotlin 的写法
MainActivity::class.java

extends 关键字

  • Java 的写法
public class MainActivity extends AppCompatActivity {
    
}
  • Kotlin 的写法(在 Kotlin 中被继承类必须被 open 关键字修饰)
class MainActivity : AppCompatActivity() {
    
}

volatile 关键字

  • Java 的写法
volatile ThreadPoolManager instance
  • Kotlin 的写法
@Volatile
var instance: ThreadPoolManager

synchronized 关键字

  • Java 的写法
// 方法上面定义同步锁
public synchronized ThreadPoolManager getInstance() {
    
}
// 方法里面定义同步锁
public ThreadPoolManager getInstance() {

    synchronized (ThreadPoolManager.class) {

    }
}
  • Kotlin 的写法
@Synchronized
fun getInstance(): ThreadPoolManager? {

}
fun getInstance(): ThreadPoolManager? {

    synchronized(ThreadPoolManager::class.java, {
        
    })
}

final 关键字

  • Java 的写法
// 表示变量不可重新赋值
final String text = "";
// 表示方法不能被重写
public final void test() {

}
// 表示类不能被继承
public final class MainActivity extends AppCompatActivity {
    
}
  • Kotlin 的写法
// 表示变量不可重新赋值
val text = ""
// 表示方法不能被重写
fun test() {

}
// 表示类不能被继承
class MainActivity : AppCompatActivity() {
    
}
  • 需要注意的是:Kotlin 的类和方法默认是不能被继承和重写的,如果想要被继承或者重写必须要使用 open 关键字进行修饰

变量

  • Java 的写法
String text = "";
  • Kotlin 的写法
var text: String = ""

静态常量

  • Java 的写法
public class MainActivity extends AppCompatActivity {
    
    static final String TEXT = "";
}
  • Kotlin 的写法(有两种写法,二选一即可)
class MainActivity : AppCompatActivity() {

    companion object {

        const val TEXT: String = ""
    }
}
const val TEXT: String = ""
    
class MainActivity : AppCompatActivity() {
    
}

定义方法

  • Java 的写法
public void test(String message) {

}
  • Kotlin 的写法(Unit 跟 void 一样效果)
fun test(message: String): Unit {

}
// 在 Kotlin 可以省略 Unit 这种返回值
fun test(message: String) {

}

重载方法

  • Java 的写法
public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}
  • Kotlin 的写法
class MainActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}

基本数据类型

  • Java 的写法
int i = 1;
long l = 2;
boolean b = true;
float f = 0;
double d = 0;
char c = 'A';
String s = "text";
  • Kotlin 的写法
var i: Int = 1
var l: Long = 2
var b: Boolean = true
var f: Float = 0F
var d: Double = 0.0
var c: Char = 'A'
var s: String = "text"
// 更简洁点可以这样,自动推导类型
var i = 1
var l = 2
var b = true
var f = 0F
var d = 0.0
var c = 'A'
var s = "text"

比较类型

  • Java 的写法
if ("1" instanceof String) {

}

if (!("2" instanceof String)) {

}
  • Kotlin 的写法
if ("1" is String) {

}

if ("2" !is String) {

}

比较对象

  • Java 的写法
// 比较两个对象内容是否一样
if (object1.equals(object2)) {

}
if (!object3.equals(object4)) {

}

// 比较两个对象是否是同一个
if (object5 == object6) {

}

if (object7 != object8) {

}
  • Kotlin 的写法
// 比较两个对象内容是否一样
if (object1 == object2) {

}
if (object3 != object4) {

}

// 比较两个对象是否是同一个
if (object5 === object6) {

}

if (object7 !== object8) {

}
  • 需要注意的是:Kotlin 中 == 和 Java 中的 equals 效果是一样的,而 Kotlin 中 ===Java== 的效果是一样的。

转换符

  • Java 的写法
int number = 100;
System.out.println(String.format("商品数量有%d", number));
  • Kotlin 的写法
var number = 100
println("商品数量有${number}")
// 换种简洁的写法
var number = 100
println("商品数量有$number")
// 如果不想字符串被转义可以使用\$
var number = 100
println("商品数量有\$number")

数组

  • Java 的写法
int[] array1 = {1, 2, 3};
float[] array2 = {1f, 2f, 3f};
String[] array3 = {"1", "2", "3"};
  • Kotlin 的写法
val array1 = intArrayOf(1, 2, 3)
val array2 = floatArrayOf(1f, 2f, 3f)
val array3 = arrayListOf("1", "2", "3")

循环

  • Java 的写法
String[] array = {"1", "2", "3"};

for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);
}
  • Kotlin 的写法
val array = arrayListOf("1", "2", "3")

for (i in array.indices) {
    println(array[i])
}

角标循环

  • Java 的写法
String[] array = {"1", "2", "3"};

for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);
}
  • Kotlin 的写法(这种写法在 Kotlin 中称之为区间)
val array = arrayListOf("1", "2", "3")

for (i in IntRange(0, array.size - 1)) {
    println(array[i])
}
// 换种更简洁的写法
val array = arrayListOf("1", "2", "3")

for (i in 0..array.size - 1) {
    println(array[i])
}
// 编译器提示要我们换种写法
val array = arrayListOf("1", "2", "3")

for (i in 0 until array.size) {
    println(array[i])
}

高级循环

  • Java 的写法
String[] array = {"1", "2", "3"};

for (String text: array) {
    System.out.println(text);
}
  • Kotlin 的写法
val array = arrayListOf("1", "2", "3")

for (text in array) {
    println(text)
}

判断器

  • Java 的写法
int count = 1;

switch (count) {
    case 0:
        System.out.println(count);
        break;
    case 1:
    case 2:
    case 3:
        System.out.println(count);
        break;
    case 5:
    case 7:
        System.out.println(count);
        break;
    default:
        System.out.println(count);
        break;
}
  • Kotlin 的写法
val count = 1

when (count) {
    0 -> {
        println(count)
    }
    in 1..3 -> {
        println(count)
    }
    5, 7 -> {
        println(count)
    }
    else -> {
        println(count)
    }
}
// 换种更简洁的写法
val count = 1

when (count) {
    0 -> println(count)
    in 1..3 -> println(count)
    5, 7 -> println(count)
    else -> println(count)
}

构造函数

  • Java 的写法
public class MyView extends View {

    public MyView(Context context) {
        this(context, null);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}
  • Kotlin 的写法
// 第一种写法
class MyView : View {
    
    constructor(context: Context) : this(context, null) {
    
    }
    
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {
    
    }
    
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
    
    }
}
// 第二种写法
class MyView : View {
    
    constructor(context: Context) : this(context, null)
    
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    
    init {
    
    }
}
// 第三种写法
class RegexEditText @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    init {
    
    }
}
// 如果只有一种构造函数的还可以这样写
class MyView(context: Context) : View(context) {
    
    init {
    
    }
}

创建类

  • Java 的写法
public class Person {

    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Person person = new Person("Android轮子哥", 100);
person.setName("HJQ");
person.setAge(50);
System.out.println("name: " + person.getName() + ", age: " + person.getAge());
  • Kotlin 的写法(如果不想暴露成员变量的set方法,可以将 var 改成 val )
class Person {
    
    var name: String? = null
    get() = field
    set(value) {field = value}
    
    var age: Int = 0
    get() = field
    set(value) {field = value}
}
// 换种更简洁的写法
class Person(var name: String, var age: Int)
var person = Person("Android轮子哥", 100)
person.name = "HJQ"
person.age = 50
println("name: {$person.name}, age: {$person.age}")

私有化 set 方法

  • Java 的写法
public class Person {

    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    private void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    private void setAge(int age) {
        this.age = age;
    }
}
  • Kotlin 的写法
class Person {
    
    var name: String? = null
    private set
    
    var age: Int = 0
    private set
}

私有化 get 方法

  • Java 的写法
public class Person {

    String name;
    int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    private String getName() {
        return name;
    }
    
    private void setName(String name) {
        this.name = name;
    }
    
    private int getAge() {
        return age;
    }
    
    private void setAge(int age) {
        this.age = age;
    }
}
  • Kotlin 的写法
class Person {
    
    private var name: String? = null
    
    private var age: Int = 0
}

枚举

  • Java 的写法
enum Sex {

    MAN(1), WOMAN(2);

    Sex(int type) {}
}
  • Kotlin 的写法
enum class Sex (var type: Int) {
    
    MAN(1), WOMAN(2)
}

接口

  • Java 的写法
public interface Callback {

    void onSuccess();
    
    // JDK 8 新特性,接口方法支持默认实现
    default void onFail() {
    
    }
}
  • Kotlin 的写法
interface Callback {

    fun onSuccess()
    
    fun onFail() {
    
    }
}

匿名内部类

  • Java 的写法
post(new Runnable() {
    
    @Override
    public void run() {
        
    }
});
  • Kotlin 的写法
post(object : Runnable {

    override fun run() {
        
    }
})

内部类

  • Java 的写法
public class MainActivity extends AppCompatActivity {

    public class MyTask {

    }
}
  • Kotlin 的写法
class MainActivity : AppCompatActivity() {

    inner class MyTask {
        
    }
}

内部类访问外部类同名变量

  • Java 的写法
String name = "Android轮子哥";

public class MyTask {

    String name = "HJQ";

    public void show() {
        System.out.println(name + "---" + MainActivity.this.name);
    }
}
  • Kotlin 的写法
var name = "Android轮子哥"

inner class MyTask {

    var name = "HJQ"

    fun show() {
        println(name + "---" + this@MainActivity.name)
    }
}

抽象类

  • Java 的写法
public abstract class BaseActivity extends AppCompatActivity implements Runnable {

    abstract void init();
}
  • Kotlin 的写法
abstract class BaseActivity : AppCompatActivity(), Runnable {
    
    abstract fun init()
}

静态变量和方法

  • Java 的写法
public class ToastUtils {

    public static Toast toast;

    public static void show() {
        toast.show();
    }
}
  • Kotlin 的写法(在 Kotlin 将这种方式称之为伴生对象)
companion object ToastUtils {

    var toast: Toast? = null

    fun show() {
        toast?.show()
    }
}

可变参数

  • Java 的写法
public int add(int... array) {
    int count = 0;
    for (int i: array) {
        count += i;
    }
    return count;
}
  • Kotlin 的写法
fun add(vararg array: Int): Int {
    var count = 0
    //for (i in array) {
    //    count += i
    //}
    array.forEach {
        count += it
    }
    return count
}

泛型

  • Java 的写法
public class Bean<T extends String> {

    T data;
    
    public Bean(T t) {
        this.data = t;
    }
}
Bean<String> bean = new Bean<>("666666");
  • Kotlin 的写法
class Bean<T : Comparable<String>>(t: T) {
    var data = t
}
var bean = Bean<String>("666666")
// 换种更简洁的写法
var bean = Bean("666666")

构造代码块

  • Java 的写法
public class MainActivity extends AppCompatActivity {
    
    int number;
    
    {
        number = 1;
    }
}
  • Kotlin 的写法
class MainActivity : AppCompatActivity() {
    
    var number = 0
    
    init {
        number = 1
    }
}

静态代码块

  • Java 的写法
public class MainActivity extends AppCompatActivity {
    
    static int number;
    
    static {
        number = 1;
    }
}
  • Kotlin 的写法
class MainActivity : AppCompatActivity() {
    
    companion object {
        
        var number = 0
        
        init {
            number = 1
        }
    }
}

方法代码块

  • Java 的写法
void test(){
    {
        int a = 1;
    }
}
  • Kotlin 的写法
fun test() {
    run {
        var a =1
    }
}

三元运算符

  • Java 的写法
int c = a > b ? a : b;
  • Kotlin 的写法
var c = if (a > b) a else b

权限修饰符

  • Java 的写法(默认为 default
修饰符作用
public所有类可见
protected子类可见
default同一包下的类可见
private仅对自己类可见
  • Kotlin 的写法(默认为 public
修饰符作用
public所有类可见
internal同 module 下的类可见
protected子类可见
private仅对自己类可见

抑制代码警告

  • Java 的写法
@SuppressWarnings("unused")

@SuppressLint("ClickableViewAccessibility")
  • Kotlin 的写法
@Suppress("unused")

@Suppress("ClickableViewAccessibility")

注解处理器

  • Java 的写法
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
  • Kotlin 的写法
apply plugin : 'kotlin-kapt'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
  • 如果在 Kotlin 仍然使用 annotationProcessor 来集成注解处理器,那么会导致报错编译不过去

下一篇:全民 Kotlin:你没有玩过的全新玩法

另外推荐一个 Kotlin 语言编写的开源项目,大家感兴趣可以看看:AndroidProject-Kotlin

Android 技术讨论 Q 群:10047167