以下内容纯粹为本人学习期间总结,如有错误之处烦请指正不胜感激😄
此次学习分享的内容均是Kotlin
入门基础语法;协程,Anko
,扩展属性等等还没涉及到
继承
- Java
class A extends B { }
- Kotlin
class A : B() {}
接口
- Java
class A implements B, C {}
- Kotlin
class A : B, C {}
override
在
Java
中是注解。重写父类方法,实现接口方法
在Kotlin
中成了类似关键字的东西。重写和实现自带了,不再是注解
- Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
- Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
Object 类
-
Java
中Object
是所有类型的顶级父类 -
Kotlin
中并没有Object
,取而代之的是Any()
,意义和Java
中的Object
一样。注意此处指的是大写O
的Object
,非小写o
的object
结扎关键字
-
Java
和Kotlin
都不能继承自结扎类 -
Java
中用final
修饰的类不可被继承,并且Java
中的类不声明为final
的话则默认可被继承 -
Kotlin
中则和Java
相反,Kotlin
中的类默认是被结扎的,不可被继承,除非使用了open
关键字 -
Kotlin
中如果某个类被声明为abstract
,则不需要使用open
进行修饰了,默认已经带上
实例化对象
- Java
Person person = new Person(bug, 需求);
- Kotlin
var person = Person(bug, 需求)
打印日志
- Java
System.out.print("打印日志");
System.out.println("打印日志");
- Kotlin
print("打印日志")
println("打印日志")
常量与变量
- Java
String name = "Hello Java";
final String name = "Hello 结扎过的 Java";
- Kotlin
var name = "Hello Kotlin"
val name = "Hello 结扎过的 Kotlin"
null声明
- Java
String otherName;
otherName = null;
- Kotlin
//在类型后面跟英文问号代表此变量可空
var otherName : String?
otherName = null
空判断
- Java
if (text != null) {
int length = text.length();
}
- Kotlin
text?.let {
val length = text.length
}
// 简单写法
val length = text?.length
字符串拼接
- Java
String firstName = "ja";
String lastName = "va";
String message = "名字是: " + firstName + " " + lastName;
- Kotlin
val firstName = "Ko"
val lastName = "tlin"
val message = "名字是: $firstName $lastName"
换行
- Java
String text = "第一行\n" +
"第二行\n" +
"第三行";
- Kotlin
//又叫多行文本字符串
val text = """
|第一行
|第二行
|第三行
""".trimMargin()
//trimMargin()方法是Kotlin自己的,用于替换掉字符串中的指定符号,点击查看源码可知默认值是"|",所以我们可以依照自己的需求来进行替换
val text = """
>First Line
|Second Line
>Third Line
""".trimMargin(">")
//这样就只会替换掉第一行和第三行前面的大于符号
三目运算符
- Java
String text = x > 5 ? "x > 5" : "x <= 5";
- Kotlin
val text = if (x > 5)
"x > 5"
else "x <= 5"
//简单写法
var s: String? = null
var text = s ?: "空了" //s为空么?不为空返回自己,为空返回"空了"
操作符
- java
final int andResult = a & b;
final int orResult = a | b;
final int xorResult = a ^ b;
final int rightShift = a >> 2;
final int leftShift = a << 2;
- Kotlin
val andResult = a and b
val orResult = a or b
val xorResult = a xor b
val rightShift = a shr 2
val leftShift = a shl 2
类型判断和转换 (声明式)
- Java
if (object instanceof Car) {
}
Car car = (Car) object;
- Kotlin
if (object is Car) {
}
var car = object as Car
类型判断和转换 (隐式)
- Java
if (object instanceof Car) {
Car car = (Car) object;
}
- Kotlin
if (object is Car) {
var car = object // smart casting
}
多重条件
- Java
if (score >= 0 && score <= 300) { }
- Kotlin
if (score in 0..300) { }
更灵活的case语句
- Java
int score = // some score;
String grade;
switch (score) {
case 10:
case 9:
grade = "Excellent";
break;
case 8:
case 7:
case 6:
grade = "Good";
break;
case 5:
case 4:
grade = "OK";
break;
case 3:
case 2:
case 1:
grade = "Fail";
break;
default:
grade = "Fail";
}
- Kotlin
var score = // some score
var grade = when (score) {
9, 10 -> "Excellent"
in 6..8 -> "Good"
4, 5 -> "OK"
in 1..3 -> "Fail"
else -> "Fail"
}
for循环
- Java
for (int i = 1; i <= 10 ; i++) { }
for (int i = 1; i < 10 ; i++) { }
for (int i = 10; i >= 0 ; i--) { }
for (int i = 1; i <= 10 ; i+=2) { }
for (int i = 10; i >= 0 ; i-=2) { }
for (String item : collection) { }
for (Map.Entry<String, String> entry: map.entrySet()) { }
- Kotlin
for (i in 1..10) { }
for (i in 1 until 10) { }
for (i in 10 downTo 0) { }
for (i in 1..10 step 2) { }
for (i in 10 downTo 1 step 2) { }
for (item in collection) { }
for ((key, value) in map) { }
更方便的集合操作一
- Java
final List<Integer> listOfNumber = Arrays.asList(1, 2, 3, 4);
final Map<Integer, String> keyValue = new HashMap<Integer, String>();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
// Java 9
final List<Integer> listOfNumber = List.of(1, 2, 3, 4);
final Map<Integer, String> keyValue = Map.of(1, "Java",
2, "Kotlin",
3, "Scala",
4, "Swift");
- Kotlin
val listOfNumber = listOf(1, 2, 3, 4)
val keyValue = mapOf(1 to "Java",
2 to "Kotlin",
3 to "Scala",
4 to "Swift")
更方便的集合操作二
- Java
List<String> list = new ArrayList();
list.add("Java");
list.add("Kotlin");
list.add("Scala");
list.add("Swift");
Map<Integer, String> map = new HashMap();
map.put(1, "Java");
map.put(2, "Kotlin");
map.put(3, "Scala");
map.put(4, "Swift");
- Kotlin
var list = mutableListOf<String>()
list.add("Java")
list.add("Kotlin")
list.add("Scala")
list.add("Swift")
var map = mutableMapOf<Int, String>()
map.put(1, "Java")
map.put(2, "Kotlin")
map.put(3, "Scala")
map.put(4, "Swift")
遍历
- Java
// Java 7 和以前
for (Car car : cars) {
System.out.println(car.speed);
}
// Java 8+
cars.forEach(car -> System.out.println(car.speed));
// Java 7 和以前
for (Car car : cars) {
if (car.speed > 100) {
System.out.println(car.speed);
}
}
// Java 8+
cars.stream().filter(car -> car.speed > 100).forEach(car -> System.out.println(car.speed));
- Kotlin
cars.forEach {
println(it.speed)
}
cars.filter { it.speed > 100 }
.forEach { println(it.speed)}
方法定义
- Java
void doSomething() {
}
void doSomething(int... numbers) {
}
- Kotlin
fun doSomething() {
}
fun doSomething(vararg numbers: Int) {
}
带返回值的方法
- Java
int getScore() {
return score;
}
- Kotlin
fun getScore(): Int {
return score
}
//可直接在方法后返回
fun getScore(): Int = score
无结束符号
- Java
int getScore(int value) {
return 2 * value;
}
- Kotlin
fun getScore(value: Int): Int {
return 2 * value
}
//可直接在方法后返回
fun getScore(value: Int): Int = 2 * value
constructor 构造器
- Java
public class Utils {
private Utils() {
}
public Utils(Int i ,String s){
}
}
- Kotlin
class Utils constructor(i: Int, s: String) {
//这种方式的构造器是显示构造器,声明类的时候定好构造方法,实例化的时候必须按照参数列表进行实例化
var utils = Utils(1, "")
}
class Utils (i: Int, s: String) {
//上面的方式可省略 constructor 关键字
var utils = Utils(1, "")
}
class Utils {
constructor(i: Int, s: String)
//上面同样可以写成这种样子,构造函数单独写进类里面
var utils = Utils(1, "")
}
class Utils private constructor(i: Int, s: String) {
//如果 constructor 前面有修饰符,则不能省略
var utils = Utils()
}
class Utils private constructor() {
constructor(i: Int, s: String) : this() {
//这种声明表示我们有一个私有的构造方法,无参的,也可以有参,自己定义就好;然后我们公开了一个有参的构造方法供外部进行实例化
var utils = Utils(1, "")
}
}
class Utils constructor(i: Int = 2, s: String = "") {
//如果构造方法中给定了默认值,那么在实例化对象的时候可以不传入参数,不传的话实例化出来的对象默认参数就是构造方法中的参数
var utils = Utils()
var utils = Utils(1)
var utils = Utils("")
var utils = Utils(1, "")
}
class Utils constructor(i: Int, s: String = "") {
//但如果参数列表中有那种没有给定值的变量时,实例化时必须要将他们都传入构造方法
var utils = Utils(1)
var utils = Utils(1, "")
}
//引申内容,方法重载,注意和下面的 Kotlin 扩展函数区别开
class MainActivityKotlin {
override fun onCreate(saveInstance: Bundle?) {
super.onCreate(savedInstanceState)
makeToast()
makeToast("test")
makeToast(time = Toast.LENGTH_LONG)
makeToast("test", Toast.LENGTH_LONG)
makeToast(msg = "test", time = Toast.LENGTH_LONG)
}
fun makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, msg, time).show()
}
}
Kotlin 扩展函数
- Kotlin
//扩展函数一般用在工具类的封装上,可以对现有的函数在不继承的情况下进行扩展
//object 声明下面会讲到
//扩展函数一般写法是,fun 关键字 加上要扩展的类的类名,以及方法名
object Utils {
fun Activity.makeToast(msg: String = "msg", time: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, msg, time).show()
}
}
//调用时如下
//从调用处的包引入`import com.danlu.kotlindemo.Utils.makeToast`可以知道,扩展函数实际上是以静态被引入的,事实上它是静态解析的
//除了扩展函数,还有扩展属性
class MainActivityKotlin : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
makeToast()
makeToast("test")
makeToast(time = Toast.LENGTH_LONG)
makeToast("test", Toast.LENGTH_LONG)
makeToast(msg = "test", time = Toast.LENGTH_LONG)
}
}
Get Set 构造器
- Java
public class Developer {
private String name;
private int age;
public Developer(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;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Developer developer = (Developer) o;
if (age != developer.age) return false;
return name != null ? name.equals(developer.name) : developer.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Developer{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- Kotlin
data class Developer(val name: String, val age: Int)
静态
- Java
public class Utils {
private Utils() {
}
public static int getDBVersion() {
return CURRENT_DB_VERSION;
}
}
int db_verison = Utils.getDBVersion();
- Kotlin
Kotlin
中使用object
修饰静态类,被修饰的类,可以使用类名.方法名
的形式调用
object Utils {
fun getDBVersion(): Int {
return CURRENT_DB_VERSION
}
}
var db_verison = Utils.getDBVersion()
Kotlin
中使用companion object
修饰静态方法,称为伴生对象,可以使用类名.方法名
的形式调用
class Utils {
companion object {
fun getDBVersion(): Int {
return CURRENT_DB_VERSION
}
}
}
var db_verison = Utils.getDBVersion()
权限修饰符
Java
- public 对所有类可见
- default 在同一包内可见,不写默认
default
- protected 对同一包内的类和所有子类可见
- private 在同一类内可见
Kotlin
- public 凡是能够访问到这个类的地方, 同时也能访问这个类的
public
成员,不写默认是public
- internal 在
module
之内, 凡是能够访问到这个类的地方, 同时也能访问到这个类的internal
成员 - protected 与
private
一样, 另外在子类中也可以访问 - private 表示只在这个类(以及它的所有成员)之内可以访问,不会自动生成
getter setter
方法
标签(@)
- Java
loop:
for (int i = 0; i < 100; i++) {
loop1:
for (int j = 0; j < 100; j++) {
if (i == 3) {
continue loop1;
} else if(i == 5) {
continue loop;
} else {
break loop1;
}
}
}
Java
中的标签我们用的极少,它主要是用来控制流程语句的执行,continue
,break
。用法是:在语句内部需要continue
,break
的地方,在控制关键字后跟上你想控制的某个循环。简单地说就是,一个循环一组标签,起始和终止位置标签内容一致。在循环内部,任意地方可以控制其他循环。为了方便跳转到指定位置-
在循环开始之前用自定义的名字加上英文冒号作为起始点,然后书写循环语句
loop:循环语句体...continue/break loop;
Kotlin
val ints = intArrayOf(1, 2, 3, 0, 4, 5, 6)
ints.forEach foreach@ {
if (it == 0) return@foreach
print(it)
}
- 由于
Kotlin
中几乎万物都是表达式,所以会有方法后直接跟运算体的写法。Kotlin
中的标签和Java
中大同小异,只不过在循环控制上多了return
,用来指定:在指定位置返回,上面的代码就说明在 it== 0时返回,不打印,所以打印结果是 123456 - 另外
Kotlin
中的标签还可以用在this
关键字上。Java
中我们通常有XXXActivity.this
的写法,用来代指XXXActivity
这个引用,Kotlin
中写法是this@XXXActivity
init代码块
class Test public constructor(val i: Int) {
// 只对主构造方法生效
init {
}
constructor(i: Int, s: String) : this(i) {
}
fun xxx() {
}
}
上述代码中,定义了
Test
类的两个构造方法,参数列表不同;实例化时可以:val test = Test(1) val test1 = Test(1, "")
而某些操作可能需要在默认/主构造方法中进行初始化,也就是单参数的构造方法中,所以这时候就有
init
代码块;Kotlin
主构造函数不能包含任何的代码,所以初始化的代码可以放到init
块中进行
lateinit 和 by lazy
对象/变量可以通过依赖注入来初始化, 或者在单元测试的
setup
方法中初始化。 这种情况下,我们并不能直接在构造方法内提供一个非空构造器,但我们使用时依然想要避免对象/变量的空问题,所以。。。
-
lateinit
意思是延迟初始化,只有当变量/对象被声明为var
时才可使用 -
by lazy
意思是懒初始化,只有当变量/对象被声明为val
时才可使用
// by lazy 使用方式后面跟大括号,里面进行对象/变量的实例化/赋值
// by lazy 只会在第一次使用 danluUtil / name / id 的时候才会创建对象或者实例初始化变量
// 和 java 中的懒汉式单例一样,使用时候判空,不为空直接返回对象,为空的话实例化对象再返回
val danluUtil by lazy {
DanluUtil(i, j)
}
val name by lazy {"名字"}
val id by lazy {1}
// lateinit 使用方式在 var 前面加上 lateinit 即可,后面跟上变量和变量类型
// lateinit 声明的变量/对象,不能为空,也不能被立即初始化:比如下面两种方式都是不允许的:
// lateinit var danluUtil: DanluUtil = DanluUtil(i, j)
// lateinit var danluUtil: DanluUtil?
// 大致来说,这段代码将变量的初始化与定义分离开了
// 使用场景包括但不限于依赖注入框架(例如 Dagger2),那些预先声明的变量也无法成功初始化。在这种情况下,必须使用 lateinit 关键字确保变量在稍后将被初始化
lateinit var danluUtil: DanluUtil
// 声明完毕后在需要用到的地方进行初始化:
danluUtil = DanluUtil(i, j)