1. Why use Kotlin for Android?
Since The acquisition of Java by Oracle, Google has often been sued by Oracle for copyright, so Google chose Kotlin as the first language for Android development. According to the Android website, Kotlin is free and open, a static programming language developed by a particularly talented company called JetBrains. AndroidStudio is also based on his IDEA, Google also contributed to the advantages of open-source Kotlin:
- Expressive and extremely concise
Kotlin’s modern language capabilities let you focus on expressing your ideas and write less boilerplate code.
- More secure code
Kotlin helps you avoid NullPointerExceptions with @Nullable and @nonNULL contained in its type system. Android apps that use Kotlin are 20% less likely to crash.
- interoperable
Can interwork with Java code and call each other
- Structured concurrency
Kotlin coroutines simplify asynchronous programming, allowing you to perform common tasks such as network calls and database updates easily and efficiently.
2. Basic grammar
2.1, variables,
Type inference Is derived according to the type of initialization for type variable variable val var immutable variables definition is equivalent to the final of the Java modified Kotlin is a static language, compile time decided to things
class VariableDemo {
// var < identifier > : < type > = < initialization value >
// val < identifier > : < type > = < initialization value >
// var userName:String=" "
var name="Aimes"// Automatically deduce to string
val age=100// Automatically derive to Int
}
Copy the code
Code decompiledJava (a plug-in that converts Kotlin into bytecode and decompiles it into a Java file)
public final class VariableDemo {
@NotNull
private String name = "Aimes";
private final int age = 100;
@NotNull
public final String getName(a) {
return this.name;
}
public final void setName(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "
"
?>);
this.name = var1;
}
public final int getAge(a) {
return this.age; }}Copy the code
Var can be read and written; val can be read and written; val can be read and not written
2.2, functions,
The method void==Unit that does not return a value can be omitted
fun testFun(number1:Int,number2:Int):Unit{
println(number1+number2)
}
Copy the code
A method with a return value and an argument
fun testFun(number1:Int,number2:Int):Int{
println(number1+number2)
return number1+number2
}
Copy the code
A more advanced way to write this = derive the return value type
fun add(number1: Int,number2: Int) = number1+number2 // The return value is derived as Int
fun add3(number1: Int, number2: Int) = "Aimes"// The return value is derived as String
Copy the code
In Java, you can have variable arguments. In Kotlin, you need to use the vararg keyword to modify variable arguments.
fun lenMethod(vararg number:Int){
println(number.size)
}
Copy the code
Lambda expression functions (here’s an example, I’ll write a post about lambda later)
fun main(a){
// Lambda expression function
val addMethod : (Int.Int) - >Int = {number1, number2 -> number1 + number2}
val r= addMethod(9.9)
println(r)
}
Copy the code
2.3 string template
It’ll be a little faster
val name = "Aimes"
val age = 28
val sex = 'M'
val info = "ABCDEFG"
println("name:$name, age:$age, sex:$sex info:$info")
Copy the code
Three double quotes, output as is, no escaping characters for newlines,
val infoMesage = """ AAAAAAAAAAA"aaa" BBBBBBBBBBB CCCCCCCCCCC DDDDDDDDDDD EEEEEEEEEEE """ // Front space
println(infoMesage)// The output will have a leading space
val infoMesage2 = """ AAAAAAAAAAA BBBBBBBBBBB CCCCCCCCCCC DDDDDDDDDDD EEEEEEEEEEE """.trimIndent() / / no Spaces
Copy the code
TrimIndent () removes the front space and displays 999.99999.99999.99999.99999.99 {‘ $’}999
val price = "" "The ${'$'}99999.99 "" ".trimIndent()
println(price)
Copy the code
2.4. Null check is one of Kotlin’s features
varname:String? =null/ /? A notification is sent telling all callers that the variable can now be null and that you, the callers, can take the action yourself
fun main(a) {
// If you do not fix the error, the compiler will report the error as shown in the following figure
}
Copy the code
There are three ways to fix this. The first way is to allow a null value to be returned in a method, and then add one after the return value, right? This leaves the remedy in the hands of the caller of the return value
fun main(a) {
var testStr=test()
//testStr.length
}
fun test(a):String? {return null
}
Copy the code
The error in teststr. length is the same as the error in teststr. length. Teststr.length is not allowed to return null. Teststr.length is not allowed to return null. Second remedy: When calling this property, add a dot in front of it. If this property is null, then the following code will not execute
fun main(a) {
vartestStr=test() testStr? .length// If testStr is null,. Length is not executed
}
fun test(a):String? {return null
}
Copy the code
The third remedy is invoked by adding two to the front of the dot!! This attribute must not be null
fun main(a) {
vartestStr=test() testStr!! .length// If testStr is null,. Length is not executed
}
fun test(a):String? {return null
}
Copy the code
The third remedy must be used with caution, if the attribute is 100% non-null, otherwise a null pointer exception will occur
2.5, interval
fun sectionTest(a){
/ / range.. You can only count from small to large
for (index in 1.10.){
print(index)
}
println("")
// The interval down to can only be from large numbers to decimal numbers
for (index in 10 downTo 1){
print(index)
}
println("")
/ / step stride
for (index in 1.10. step 4){
print(index)
}
// In and downTo are closed interval unitl half closed and half open interval
// Half-closed and half-open intervals can only be from small numbers to large numbers
for(index in 1 until 10){
print(index)
}
}
Copy the code
Output results:
3. Compare and array
Equals equals (), but the yellow wavy line === compares the address of the object
val name1: String = "Aimes"
val name2: String = "Aimes"
// -- compare the value itself
// == equals to Java
println(name1.equals(name2))
println(name1 == name2)
// -- Compare object addresses
val test1:Int? = 10000
val test2:Int? = 10000
println(test1 === test2) // false
Copy the code
ArrayOf generic type derivation
val numbers = arrayOf(1.2.3.4.5.6.7.8)
/ / value Numbers [index]
numbers[0]
2 / / way
val numbers2 = Array<String>(10, {value: Int- > ("aaa")})// val numbers2 = Array<String>
(10.// Array size
{value: Int // Array subscript -
> ("aaa")// assign aaa to value})
Copy the code
Or you could write it this way
val numbers2 = Array<String>(10, {value: Int -> if(value==5) ("666") else ("aaa")})for (value in numbers2) {
println(value)
}
Copy the code
Code after decompiledJava
public static final void main(a) {
byte var1 = 10;
String[] var2 = new String[var1];
boolean var5;
for(int var3 = 0; var3 < var1; ++var3) {
var5 = false;
String var8 = var3 == 5 ? "666" : "aaa";
var2[var3] = var8;
}
String[] var11 = var2;
int var4 = var2.length;
for(int var10 = 0; var10 < var4; ++var10) {
String value = var11[var10];
var5 = false; System.out.println(value); }}Copy the code
4. Condition control
Expression ratio size
val age=5;
val age1=10;
val maxValue=if (age>age1) age else age1
Copy the code
Interval judgment
val age=5;
if(age in 1.18.){
println("Underage")}else{
println("Come of age")}Copy the code
When is the upgraded version of switch
val age=5;
when(age){
in 1.18.- > {// Determine whether it is between 1 and 18
}
19.21.22.24- > {// If one of them is satisfied, the branch is executed
}
else- > {// Do not satisfy the above conditions to take the branch}}Copy the code
Type derivation for when
var str= when(age){
in 1.18.- > {"Age is$ageMinor"
}
19.21.22.24- > {"Age is$ageCome of age."
}
else- > {"Age is$ageAnd the other"
}
}
println(str)
Copy the code
If the return type of each branch is different, STR is derived to Any, which is the Java equivalent of Object
5. Loops and labels
Any expression in Kotlin can be marked with a tag. The format of the tag is the identifier + @ symbol. For example, aaa@ and bottom@ are valid tags. To add a tag to an expression, you only need to add a tag before it. The break tag is applied
tttt@ for (i in 1.20.) {
for (j in 1.20.) {
println("i:$i, j:$j")
if (i == 5) {
// break // j loop to break
break@tttt // I loop to break}}Copy the code
return
fun testLabel(a){
var numbers= arrayOf(1.2.3.4.5.6)
testFor@numbers.forEach {
when(it){
5- > {// return // do not print aaa
return@forEach/ / print aaa
}
}
}
println("aaa")}Copy the code
this
class SafeDemo {
val name="Aimes"
inner class SafeDemoInner{
val name="Inner Love"
fun test(a){
println(this.name)/ / inner code and love
println(this@SafeDemo.name)//}}}Copy the code
The for loop
var items = listOf<String>("Bill"."Zhang"."Fifty")
for (item in items) {
println(item)
}
items.forEach {
println(it)
}
for (index in items.indices) {
println("Subscription:$index, the corresponding value:${items[index]}")}Copy the code
6. Classes and Objects
Let’s start with an empty class
// The default is public, so you don't need to write public
class Test {}Copy the code
6.1. Construction methods
class Test(val age:Int) {// How to write the main structure
constructor() :this(5)// The secondary construct must call the primary construct
constructor(name:String):this(5)/ / structure
}
// The new keyword is not required
fun main(a) {
Test(0)}Copy the code
In Java, class is final, so it can’t be inherited, but if I want to write a parent class, what if I use open in front of class, so it can be inherited, so I drop the final keyword
open class Test(val age:Int) {// How to write the main structure
constructor() :this(5)// The secondary construct must call the primary construct
constructor(name:String):this(5)/ / structure
}
Copy the code
6.2 Default values for properties
In Java, you can have a default value for all property values, which is null, which is fine, but in Kotlini, if you don’t assign a value to a property, you get an error
- ? Allow yourself to remedy the void
- Give yourself an initial value and everybody’s happy
- Fixed with lazy loading lateinit
val number=0;
varid:String ? =null
lateinit var url:String// The null pointer will be null if it is used for lazy loading
Copy the code
6.3 Abstract Classes and Interfaces
Abstract classes and interfaces are written in a similar way to Java
interface ICallBack {
fun onCallBack(a)
}
abstract class TestAbstract {
abstract fun initView(a)
}
// Use both inheriting and implementing interfaces: then separate them with commas. When inheriting an abstract class or an open-decorated class, declare the main construct
class TestInterface: TestAbstract(),ICallBack{
override fun initView(a) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
override fun onCallBack(a) {
// TODO("not implemented") //To change body of created functions use File | Settings | File Templates.}}Copy the code
6.4 data Beans
Kotlin uses dataclass instead of Javabeans and generates copy function
data class UserBean(val userName:String,val password:String)
fun main(a) {
var user=UserBean("aaa"."bbbb")
var (username,password)=user.copy()
var (_,amszlk)=user.copy()/ / want to copypassword
println("username:$username,password:$password")
println(amszlk)
}
Copy the code
Convert to Java code
public final class UserBean {
@NotNull
private final String userName;
@NotNull
private final String password;
@NotNull
public final String getUserName(a) {
return this.userName;
}
@NotNull
public final String getPassword(a) {
return this.password;
}
public UserBean(@NotNull String userName, @NotNull String password) {
Intrinsics.checkParameterIsNotNull(userName, "userName");
Intrinsics.checkParameterIsNotNull(password, "password");
super(a);this.userName = userName;
this.password = password;
}
@NotNull
public final String component1(a) {
return this.userName;
}
@NotNull
public final String component2(a) {
return this.password;
}
@NotNull
public final UserBean copy(@NotNull String userName, @NotNull String password) {
Intrinsics.checkParameterIsNotNull(userName, "userName");
Intrinsics.checkParameterIsNotNull(password, "password");
return new UserBean(userName, password);
}
// $FF: synthetic method
public static UserBean copy$default(UserBean var0, String var1, String var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = var0.userName;
}
if ((var3 & 2) != 0) {
var2 = var0.password;
}
return var0.copy(var1, var2);
}
@NotNull
public String toString(a) {
return "UserBean(userName=" + this.userName + ", password=" + this.password + ")";
}
public int hashCode(a) {
String var10000 = this.userName;
intvar1 = (var10000 ! =null ? var10000.hashCode() : 0) * 31;
String var10001 = this.password;
returnvar1 + (var10001 ! =null ? var10001.hashCode() : 0);
}
public boolean equals(@Nullable Object var1) {
if (this! = var1) {if (var1 instanceof UserBean) {
UserBean var2 = (UserBean)var1;
if (Intrinsics.areEqual(this.userName, var2.userName) && Intrinsics.areEqual(this.password, var2.password)) {
return true; }}return false;
} else {
return true; }}}Copy the code
6.5 Kotlin’s Object and companion Object
Only one of Kotlin’s only patterns is the Object class
object ObjectTest {
fun showToast(a){}}/ / call
fun main(a) {
ObjectTest.showToast()
}
Copy the code
The code after conversion to Java
public final class ObjectTest {
public static final ObjectTest INSTANCE;
public final void showToast(a) {}private ObjectTest(a) {}static {
ObjectTest var0 = newObjectTest(); INSTANCE = var0; }}Copy the code
Since we are living in the world, we are living in the world
class CompanionObjectTest {
companion object{
val name="Aimes"
fun show(a){
name.length
}
}
}
/ / call
fun main(a) {
CompanionObjectTest.show()
}
Copy the code
After turning Java
public final class CompanionObjectTest {
@NotNull
private static final String name = "Aimes";
public static final CompanionObjectTest.Companion Companion = new CompanionObjectTest.Companion((DefaultConstructorMarker)null);
@Metadata( mv = {1, 1, 15}, bv = {1, 0, 3}, k = 1, d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0003\n\u0002\u0010 \ u0002 \ n \ \ u0086 \ u0003 u0000 \ b \ u0018 \ u00002 \ u00020 \ u0001B \ u0007 \ \ b u0002 ¢\ u0006 \ u0002 \ u0010 \ u0002J \ u0006 \ u0010 \ u0007 \ u001a \ U00020 \ bR \ u0014 \ u0010 \ u0003 \ u001a \ u00020 \ u0004X \ u0086D ¢\ u0006 \ b \ n \ u0000 \ u001a \ u0004 \ b \ u0005 \ u0010 \ u0006 ¨ \ u0006 \ t "}, d2 = {"Lsimple01/CompanionObjectTest$Companion;" , "", "()V", "name", "", "getName", "()Ljava/lang/String;" , "show", "", "kotlindemo"} )
public static final class Companion {
@NotNull
public final String getName(a) {
return CompanionObjectTest.name;
}
public final void show(a) {
((CompanionObjectTest.Companion)this).getName().length();
}
private Companion(a) {}// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this(a); }}}/ / call
public static final void main(a) {
CompanionObjectTest.Companion.show();
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
Copy the code
A Companion object is an object that is born with it, and when the class is initialized, the Companion object Companion is instantiated, and the Companion object’s properties become static variables of the class. When a method is called, the class calls the Companion Companion property Companion directly, and then calls the show method
Kotlin’s inner class
class Test {
val I = "AAAA"
// This is not an inner class. All members of the outer class cannot be retrieved
// Nested class = You can write another class inside the class, but it is not an inner class
class Sub {
fun show(a) {
println()
}
class A {
class B {
class C {}}}}// This is the inner class
inner class Sub2 {
fun show(a) {
println(I)
}
}
}
Copy the code