class

Interfaces & Abstract Classes & Enumerations & Annotations

/ / interface
interface KotlinInterface { ...}
/ / abstract classes
abstract class KotlinAbstractClass { ...}
// enumerate "Java only uses enum as a keyword"
enum class KotlinEnum { ...}
// annotate "Java is @interface"
annotation class KotlinAnotation { ...}
Copy the code

The constructor

// Example 1: nonparametric structure & parametric structure
class KotlinInfo {
    var str1: String? = null
    var str2: String? = null
  	// The body of a function has no logic and the braces can be omitted
    constructor() {}
    constructor(str1: String? , str2: String?) {this.str1 = str1
        this.str2 = str2
    }
}
// Example 2: Override the superclass constructor
// See? We don't have parentheses when we inherit from View, because we're overwriting the constructor of View, and we actually have shorthand
class KotlinView : View {
    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
}
Copy the code

Inheritance & Implementation

Both are used by: to modify, by, to separate the class from the interface, interface and class order is not restricted.

class KotlinActivity : AppCompatActivity(), View.OnClickListener{}
Copy the code

Access to the class

// Get kotlin's class
KotlinActivity::class
// Get the Java class
JavaActivity::class.java 
Copy the code

Object & Any

In Java, all classes are subclasses of Object, and Kotlin is Any, which is the equivalent of Object in Java;

Any is simpler than Object, with only three methods equals() hashCode() toString().

The inner class

Anonymous inner class

Implement anonymous inner classes using the object keyword

// The interface has no constructor
// Therefore, there is no need for parentheses after OnClickListener
val button = Button(context)
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?).{}})Copy the code
Static inner class

The default inner class in Kotlin is a static inner class, so you can modify functions to be static without modifying the class;

Nested inner classes

Since static inner classes are the default, how do you change them to nested inner classes?

class StaticInnerClass { ...} // The default is static inner class
inner class InnerClass { ...} // Change to nested inner classes
Copy the code

this

// Java gets the target class reference through "class name.this"
MainActivity.this.finish();
// Kotlin gets the target class reference with "this@class name"
this@MainActivity.finish()
Copy the code

visibility

Kotlin’s default visible modifier is public, and Kotlin does not have package access; The new internal visibility modifier indicates that the current module is visible; For example, the current Moudle is visible during component development. Make the current module visible when making an SDK or open source library.

function

Function declaration

No return value in Java is void; Kotlin is Unit; Unit can be omitted when there is no return value;

// No input parameter, no return value
fun main(a): Unit { ...}
// There are input parameters and return values
fun addNum(num1: Int, num2: Int): Int {
  return num1 + num2
}
Copy the code

setter & getter

Kotlin generates setter&getter methods by default when declaring variables. Note that val only generates getters.

But what if we need to do something in setter&getter?

class KotlinInfo{
	var str: String? = null
        set(value) {
          	// Field is itself
            field = value
        }
        get() {
            return field
        }
  // I don't want set&get methods when I call in Java, I just want to call variables directly
  // Kotlin generates set&get by default
  // Use this variable in Java only through set&get
  Set&get cannot be called in kotlin. The default is set&get
}
Copy the code

** Extension: ** In Kotlin we always specify and assign variables by their names. The setter&getter generated by Kotlin by default works in Java, but even if the variable name is public, we can only use setter&getter to call that variable.

How does Java use variables like Kotlin does? Or how do you click on variables instead of going through setter&getter?

Using the @jVMField annotation solves this pain point, but then Java calls do not have setter&getters.

@JvmField // With the @jvmField annotation, calls in Java can use variables directly, so there is no set&get
var str: String? = null
Copy the code

variable

var & val

Kotlin defines variables with the keywords var&val;

  • var: readable and writable variables;
  • val: read-only variable, equivalent to JavafinalA decorated variable;
var age: Int = 25			
val name: String = "Kotlin"
val kotlin: Kotlin = Kotlin()
Copy the code

In the usual definition, the following type can be omitted;

Kotlin, like Java, is statically typed; once the type to the right of the equals sign is determined, the variable type cannot be changed;

So just because the variable type is omitted does not mean there is no type, just that Kotlin is making type inference.

var age = 25
val name = "Kotlin"
val kotlin = Kotlin()
Copy the code

An array of

You define arrays with arrayOf

var arrayStr = arrayOf("kotlin"."java") 
Copy the code

ArrayOf automatically converts content types, but that can be problematic;

ArrayOf unboxing when it converts, so it’s actually a wrapper type, so there’s a performance cost;

So typically we specify the array content type.

var arrayInt = intArrayOf(1.2.3)
var arrayFloat = floatArrayOf(1f,2f)
Copy the code

Air safety

type

Space security design is one of the highlights of Kotlin’s design. Space security is more secure than Java because of its space security design.

  • Nullable type: Passes after the variable type?Modification;var str: String? = null strIs a nullable type that can benull;
  • Non-null type: default is;var str: String = "text" strIs a non-null type and cannot benull, an error will be reported at compile time;

In Java, @nullable & @notnull can be flagged, but in Java, it is only a warning and is not affected at compile time.

Call the operator

There are also two callers involved when using nullable types

  • !!!!!Forced call: enforced, regardless of whether the variable is null, if null will throw a null-pointer exception;
  • ? .Security call: security call, equivalent to the layer is empty check, not empty call;
maybeNull!! .setText("text") maybeNull? .setText("text")// if (maybeNull! = null) {maybeNull? .setText("text"); }
Copy the code
Platform type

Can’t a non-nullable type be nullable?

var button: Button
button = findViewById(R.id.btn)
// Button is a non-nullable type, but still has a null pointer risk
// We write a line like this
var button: Button! = findViewById<Button>(R.id.btn)
// Button! It actually hides the hint when coding, but what is it?
// Add an exclamation mark after the type. This is a platform type
// Let's look at the findViewById code
@Nullable
public abstract <T extends View> T findViewById(@IdRes int id);
// So the actual object returned by findViewById can be empty
Copy the code

lateinit

There are two premises when using lazy initialization “LateInit”

  • The variable to be decorated must be an uncontrolled type
  • The variable being decorated cannot have an initial value

Can be greatly reduced in use? To reduce the use of unnecessary nullable types;

My non-nullable variable needs to be assigned later, so let me be null at first and I’ll definitely assign it to you later

// Without lateinit it looks like this
class KotlinActivity : AppCompateActivity() {private var button: Button? = null
  override fun onCreate(savedInstanceState: Bundle?).{
  	super.onCreate(savedInstanceState) button = findViewById(R.id.button) button? .setText("btn")}}/ / added
class KotlinActivity : AppCompateActivity() {private lateinit var button: Button
  override fun onCreate(savedInstanceState: Bundle?).{
  	super.onCreate(savedInstanceState)
    button = findViewById(R.id.button)
    button.setText("text")}}Copy the code

Type conversion

Data type conversion
var floatNum: Float = 200f // Assign the value directly to float
var floatNum: Float = 200.toFloat() // Call the function conversion
Copy the code

In Kotlin everything is an object, including data types, and there are some boxing concepts like var floatNum: Float? = 200f there is a boxing operation here.

Strong type turn

Use the AS keyword to perform strong type conversion

var view: View? = null 
// is is the Java equivalent of instanceof
if (view is Button) { 
  // As is equivalent to Java strong, (Button)view
  Button button = view as Button
  button.setText("text")}// Kotlin is smart here
// When your view object is already a Button, it thinks you don't need to force it anymore
if(the viewis Button) {
	view.setText("text")}Copy the code

Not empty assertion

A nullable type is forcibly converted to a non-nullable type, which can be followed by a!! To achieve type substitution.

Compiler constant

Concept: Values are determined at compile time and never change.

Prefixes static variables with the const keyword to become compiler constants; Note that it must be in front of static variables!

other

static

The top function

Also known as package-level functions, they represent static variables or functions declared directly in Kotlin files.

package com.youaji.util
// Static variables
private val displayMetrics = Resources.getSystem().displayMetrics
// static function
fun dp2px(dp: Float): Float {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
Copy the code

When using directly use the function name or variable name, guide package together with the package name and function name or variable name import;

There will be some problems, such as when the overload or multiple files the same function name, although the guide package can be distinguished, but the recognition is not friendly; Let’s save this for later. Let’s fix the emergency point first. Is it the same with Java calls?

/ / Kotlin calls
import com.youaji.util.dp2px
val pxValue = dp2px(10f)
// A Java invocation, albeit through a class, whose name becomes UtilKt
UtilKt.dp2px(10f);
// A utill must be UtilKt
@file:JvmName("Utils")
package com.youaji.util
// The Java call looks like this
Utils.dp2px(10f);
// if the file name is Util. Kt, then Util cannot be set to Util
// The reason is not known, guess if you set it to the same as the file name is meaningless, or it will also conflict with the file name
// You can customize the name, but you can't use it in most scenarios, so there is no need to change the name
Copy the code

@file:JvmName(“name”) : @file:JvmName(“name”) : @file:JvmName(“name”) : @file:JvmName(“name”) So, although it can be customized, but the actual development is most scenarios are not used, and there is no need to modify the general situation.

object

Object can also modify static classes and implement singletons. It also resolves the above problem of not calling a function by class name.

object Util {
    private val displayMetrics = Resources.getSystem().displayMetrics
    fun dp2px(dp: Float): Float {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,displayMetrics)
    }
}
// Kotlin uses; Just like in Java, the function is called by the class name
Util.dp2px(10f)
// Use Java; There is a difference, how many INSTANCE! It's actually because of singletons
Util.INSTANCE.dp2px(10f);
Copy the code
Associated object
// Just for demonstration
class Util {
    constructor() { displayMetrics = Resources.getSystem().displayMetrics}
    companion object {
        private lateinit var displayMetrics: DisplayMetrics
        fun getDisplayMetrics(a): DisplayMetrics { return displayMetrics}
    }
}
Util.getDisplayMetrics() / / kotlin use
Util.Companion.getDisplayMetrics(); / / Java
Copy the code
extension
  • Question 1: Why did Kotlin drop static?

    Kotlin would like to avoid this situation, but the existence of top-level functions is somewhat contradictory.

  • Kotlin does not have static methods. Are these static methods used in Java?

    No, Kotlin just uses these as a more elegant alternative to Java scenarios that use static, but can still be modified as static by @jvmstatic when mixed with Java.

@JvmStatic
fun dp2px(dp: Float): Float { ...}
@JvmStatic
fun getDisplayMetrics(a): DisplayMetrics { ... }// As with Kotlin, there is no need to use INSTANCE or Companion in Java as with static methods
Util.dp2dp(10f)
Util.getDisplayMetrics();
Copy the code

string

String template

Use a string template in the ${} form

var data = "2019-07-21"
var number = Awesome!
var str = "${data}Received the transfer${number}Yuan"
// If it is a single variable, the braces can be omitted
var str = "Received the transfer"$numberYuan"
Copy the code
Multiline string

A multi-line string concatenated with “”” instead of \n

var str = "" first row, second row, third row ""
Copy the code

interval

// We can write interval judgment like this
if (num >= 200 && num < 300) {}// But we can write the interval like this
if (num in 200.299.) {}// What does that mean? Indicates whether num is in the range containing 200 and less than 300
Copy the code

when

When is comparable to the advanced version of Switch in Java because when supports expressions on conditional branches.

// Switch is the Java equivalent
when (num) {
    200 -> println("200")
    300 -> println("300")
    400 -> println("400")
    else -> println("Other")}// Match the interval expression
when (num) {
    in 200.299. -> println("> = 200 < 300")
    in 300.399. -> println("> = 300 < 400")
    in 400.499. -> println("> = 400 < 500")
    500 -> println("500")
    else -> println("Other")}Copy the code

Exception handling

In Kotlin, there is a try-catch that does not force an exception

cycle

Simply use the next loop

val kotlinInfos = ArrayList<KotlinInfo>()
/ / Java
for(KotlinInfo kotlinInfo : kotlinInfos) { ... }/ / kotlin use
for (kotlinInfo inkotlinInfos) { ... }Copy the code

annotation

You can use [] anywhere in a comment to refer to a target, instead of @param@link, etc.

open | final

Classes and functions in Kotlin are final by default, but abstract and Override are exceptions.

The problem

Basic can use, in the learning summary at the same time there are still some questions!

  • setter & getter
    • What happens by default?
    • Why can be omittedsetter&getterDirect access to variables?
    • Why don’t some of them tell you that you can just use variables?
  • Why did Kotin quitstatic? And Kotlin’s static functions are not like Java’sstatic?
  • Why doesn’t Kotlin need to force exceptions?