當前篇:全民 Kotlin:Java我們不一樣
第三篇:全民 Kotlin:協程特別篇
本文章已授權鴻洋微信公眾號轉載
隨著 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 來集成注解處理器,那么會導致報錯編譯不過去