简介
与Java对比,学习一些常用的Kotlin用法,后续会使用具体的开发实例进行训练。
对象
Java写法:MainActivity.this
Kotlin写法:this@MainActivity
类
Java写法:MainActivity.class
Kotlin写法:MainActivity::class.java
继承
Java写法:
public class MainActivity extends AppCompatActivity {
}
Kotlin写法:
class MainActivity: AppCompatActivity() {
}
变量
Java写法:
Intent intent = new Intent();
Kotlin写法:
Intent intent = Intent();
常量
Java写法:
final String text = "text";
Kotlin写法:
var text = "text"
静态常量
java写法:
public class MainActivity extends AppCompatActivity {
final static String TEXT = "text";
}
kotlin写法:
const val TEXT = "text"
class MainActivity : AppCompatActivity() {
}
定义方法
Java写法
public void method(String message) {
//body
}
kotlin写法:
fun method(message: String) : Unit {
//body
}
//Unit表示空返回值,可以省略
fun method(message: String) {
//body
}
重载方法
Java写法:
public class MainActiity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceInstance);
}
}
kotlin写法:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
}
}
基本数据类型
Java写法
int i =1;
long l = 2;
boolean b = true;
double d= 2.0;
float f = 1.0f;
char a = 'a';
String s = "text";
kotlin写法:
var i : Int = 1
var l : Long = 2
var b : Boolean = true
var d : Double = 2.0
var f : Float = 1.0F
var a : Char = 'a'
var s : String = "text"
// kotlin提供类型推断,可不说明类型
var i = 1
var l = 2
var b = true
var d = 2.0
var f = 1.0F
var a = 'a'
var s = "text"
比较类型
Java写法:
if ("" instanceOf String) {
}
Kotlin写法
if ("" is String) {
}
转换符
Java写法:
int number = 100;
System.out.println(String.format("The number is %d", number);
Kotlin写法:
var number = 100
println("The number is ${number}")
//换一种简单的写法
println("The number is $number")
字符串比较
Java写法
String s1 = "text";
String s2 = "text";
if (s1.equals(s2)) {
//do something
}
kotlin写法:
kotlin中==比较的是数值是否相等, 而===比较的是两个对象的地址是否相等
var s1 = "text"
var s2 = "text"
if (s1 == s2) {
//do something
}
数组
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]};
}
//使用角标循环
for (i in IntRange(1, array.size - 1)) {
println(array[i]};
}
//更简洁的写法1
for (i in 1..array.size - 1) {
println(array[i]};
}
//更简洁的写法2
for (i in 1 unitl array.size) {
println(array[i]};
}
高级循环
Java写法
String[] array = {"1", "2", "3"};
for (String item : array) {
System.out.println(item);
}
Kotlin写法
var array = arrayListOf("1", "2", "3");
for (item in array) {
println(item);
}
判断器
Java写法:
int count = 1;
switch(count) {
case 0:
System.out.println(count);
break;
case 1:
//fall through
case 2:
System.out.println(count);
break;
default:
System.out.println(count);
break;
}
kotlin写法:
var count = 1
when(count) {
0 -> {
println(count)
}
int 1..2 -> {
println(count)
}
else -> {
println(count)
}
}
//只有一条语句,可以省略括号
when(count) {
0 -> println(count)
int 1..2 -> println(count)
else -> println(count)
}
构造函数
Java写法
public class MyView extends View {
private MyView(Context context) {
this(context, null);
}
public MyView(Context context, @Nullable AttributSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, @Nullable AttributSet attrs, int defstyleAttr) {
super(context, attrs, defStyleAttr);
}
}
Kotlin写法:
class MyView : View {
constructor(context: Context) : this(context, null) {
}
constructor(context : Context, attrs : AttributSet?) : this(context, attrs, 0) {
}
constructor(context : Context, attrs : AttibuteSet?, defStyleAttr : Int) :
super(context, attrs, defStyleAttr) {
}
}
//括号内容为空,可以省略
class MyView : View {
constructor(context: Context) : this(context, null)
constructor(context : Context, attrs : AttributSet?) : this(context, attrs, 0)
constructor(context : Context, attrs : AttibuteSet?, defStyleAttr : Int) :
super(context, attrs, defStyleAttr)
}
//只有一种构造函数
class MyView(context : Context?) : View {
}
类创建
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("King", 37);
person.setName("James");
person.setAge(38);
System.out.println("name is " + person.getName() +
", age is " + 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("King", 37)
person.name = "James"
person.age = 38
println("name is {$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 Color {
RED(0x000), BLUE(0x222)
Color(int value) {}
}
Kotlin写法
enum class Color (var value: Int) {
RED(0x000), BLUE(0x222)
}
接口
Java写法
public interface Callback {
void onSuccess();
void onFail();
}
kotlin写法
interface Callback {
fun onSuccess();
fun onFail();
}
匿名内部类
Java写法:
new Callback() {
@Override
public void onSuccess() {
}
@Override
public void onFail() {
}
}
Kotlin写法:
object:Callback {
override fun onSuccess() {
}
override fun onFail() {
}
}
内部类
Java写法:
public class MainActivity extends AppCompatActivity {
public class MyInnerClass {
}
}
Kotlin写法:
class MainActivity : AppCompatActivity {
inner class MyInnerClass {
}
}
内部类访问外部类同名变量
Java的写法
String name = "king"
public class MyInnerClass {
String name = "james";
public void test() {
System.out.println(name + ", outer name is " + MainActivity.this.name);
}
}
Kotlin写法
var name = "king"
inner class MyInnerClass {
var name = "james"
fun show() {
println("name is $name, outer name is ${this@MainActivity.name})
}
}
抽象类
Java写法
public abstract class BaseActivity extends AppCompatActivity implements Runnable {
abstract void initViews();
}
Kotlin写法
abstract class BaseActivity : AppCompatActivity(), Runnable {
abstract fun initViews();
}
静态变量和方法
Java写法
public class Toastutils {
public static Toast sToast;
public static void show() {
sToast.show();
}
}
kotlin写法
kotlin中使用伴生对象带他static field或static function
companion object ToastUtils {
var sToast : Toast ? null
fun show() {
sToast!!.show()
}
}
可变参数
java写法
public init add(int ... array) {
int count = 0;
for (int i : array) {
count += i;
}
return count;
}
kotlin写法
fun add(vararg array: Int) : Int {
var count = 0;
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<>("123123");
Kotlin写法
class Bean<T : Comparable<String>> (t: T) {
var data = t
}
var bean = Bean<String>("123123")
// 更简洁的写法
var bean = Bean("123123");
代码块
Java写法
public class MainActivity extends AppCompatActivity {
int number;
{
number = 1;
}
}
Kotlin写法
class MainActivity : AppCompatActivity() {
var number = 1
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 {
int a = 1
}
}
可见修饰符
java写法
| 修饰符 | 作用范围 |
|---|---|
| public | 所有类可见 |
| protected | 子类可见 |
| default | 同一包下的类可见 |
| private | 仅对自己可见 |
kotlin写法
| 修饰符 | 作用范围 |
|---|---|
| public | 所有类可见 |
| internal | 同Module下可见 |
| protected | 子类可见 |
| private | 仅自己可见 |
Lambda
textView.setOnClickListener(View.OnClickListener {
fun(v : View) {
View.GONE.also { v.visibility = it }
}
})
textView.setOnClickListener { v -> v.visibility = View.GONE }
函数变量
val result = fun(number1 : Int, number2 : Int) : Int {
return number1 + number2
}
print(result(1, 2))
空安全
类型被区分为可以使用null和不能使用null的情况
var string : String = "Kotlin"
string = null //error
var string : String? = "Kotlin"
string = null //ok
安全调用
string?.length
var len = string?.length ?: -1
!!操作符
代码会主动抛出NullPointerException
var len = string!!.length
当string为null的时候,代码执行时会抛出NullPointerException
安全转换
var string: String? = "kotlin"
var int: Int? = string as? Int
如果string不是Int类型,那么int为null
可空集合
如果list包含null
val nullableList: List<Int?> = listOf(1, 2, null, 4)
val intList : List<Int> = nullableList.filterNotNull()
方法支持添加默认参数
Java中扩展方法
public void toast(String text) {
toast(this, text, Toast.LENGTH_SHORT);
}
public void toast(Context context, String text) {
toast(context, text, Toast.LENGTH_SHORT);
}
public void toast(Context context, String text, int time) {
Toast.makeText(context, text, time).show();
}
toast("弹个Toast");
toast(this, "弹个Toast");
toast(this, "弹个Toast", Toast.LENGTH_LONG);
Kotlin中可以在方法上直接定义参数的默认值
fun toast(context : Context = this, text : String, time : Int = Toast.LENGTH_SHORT) {
Toast.makeText(context, text, time).show()
}
toast("弹个Toast");
toast(this, "弹个Toast");
toast(this, "弹个Toast", Toast.LENGTH_LONG);
类方法扩展
例:不改变String的情况,扩展方法
fun String.handle() : String {
return this + " extension"
}
print("xyz: ".handle())
扩展函数
扩展函数时为了简化一些代码产生,主要包括:let、with、run、apply、also
let函数
// 作用1:使用it替代object对象去访问其公有的属性 & 方法
object.let{
it.todo()
}
// 作用2:判断object为null的操作
object?.let{//表示object不为null的条件下,才会去执行let函数体
it.todo()
}
// 注:返回值 = 最后一行 / return的表达式
//使用1
var result : Int = "king".let {
print(it.length)
1000
}
print(result)
//使用2
mCanvas?.let {
mCanvas.drawCircle()
mCanvas.drawLine()
}
also函数
类似let函数,但区别在于返回值:
- let函数:返回值 = 最后一行 或 return的表达式
- also函数:返回值 = 传入的对象的本身
//let
var result : Int = "king".let {
print(it.length)
1000
}
// result值为1000
//also
var result : Int = "king".also {
print(it.length)
1000
}
// result值为 字符串 king
with函数
调用同一个对象的多个方法 / 属性时,可以省去对象名重复,直接调用方法名 / 属性即可
var p = Person("king", 17)
with(p) {
print("name is $name, age os $age")
}
run函数
结合了let、with两个函数的作用,即:
- 调用同一个对象的多个方法 / 属性时,可以省去对象名重复,直接调用方法名 / 属性即可
- 定义一个变量在特定作用域内
- 统一做判空处理
p?.run {
print("name is $name, age os $age")
}
apply函数
与run函数类似,但区别在于返回值:
- run函数返回最后一行的值 / 表达式
- apply函数返回传入的对象的本身
var result1 = p.run {
print("name is $name, age os $age")
1024
}
//result1值为1024
var result2 = p.apply {
print("name is $name, age os $age")
1024
}
//result2值为 p对象