“Confirmed” stepped on the pit “, met the right onekotlin

Num 1: The method input parameter is constant and cannot be modified

Java programmers can get a little uncomfortable with Java and Kotlin interoperability

class Main {

    /** * the Kotlin entry is constant */
    fun print(a: Int = 1, b: String = "") {
        // a = 10; // Error: Val cannot be reassigned!}}Copy the code

Num 2: NoCompanion,INSTANCE?

Java requires Companion to access static variables as well as static methods defined in Kotlin. Such as:

// Main.kt
class Main {
  companion object {
      val EMPTY = ""

      fun isEmpty(string: String = EMPTY) {
          //todo code
      }
      
      @JvmField
      val FULL_NUMBER = "1234567890"

      @JvmStatic
      fun isNumber(string: String = FULL_NUMBER) {
          //todo code}}}Copy the code
// Test.java
class Test {
  public static void main(String[] args) {
      // Java accesses constants in Kotlin
      Keng.Companion.getEMPTY();
      Keng.Companion.isEmpty("");
      
      KengInstance.INSTANCE.getEMPTY();
      
      // Java access Kotlin constants with JvmField modifier without Companion
      String FULL_NUMBER = Keng.FULL_NUMBER;
      // Java accesses methods in Kotlin with the JvmStatic modifier, without Companion
      Keng.isNumber(""); }}Copy the code

Do not want to use Companion, @jvmField, @jVMStatic annotations to find out.

In Kotlin object Main {… } static objects defined still apply.

These annotations, especially recommended in Kotlin, allow Java to interact with Kotlin as if nothing had happened, as if nothing had changed.

Num 3: Java overloading, how to transition skillfully in Kotlin?

Kotlin calls methods in Kotlin, which can pass no arguments if they have default arguments. Java and Kotlin interoperability, still need to pass?

Example: isNumber(string: string = FULL_NUMBER) :

// Test.java
class Test {
  public static void main(String[] args) {
    Keng.isNumber("");// An argument must be passed}}Copy the code

Can Java enjoy the joys of Kotlin default parameters?

// Test.java
class Test {
  public static void main(String[] args) {
    // JvmOverloads are implemented by default
    Keng.isNumberWithOverLoads();
    Keng.isNumberWithOverLoads(""); }}Copy the code

Note: @jvMoverloads require extra attention when used with Android View architecture controls. For details, enter the portal: don’t always trust @jvMoverloads

Num 4: Void call in Kotlin

The following code, which should be fine in Java, will not compile through the compiler in Kotlin.

var nullableString: String? = null.fun testNullableString(a) {
    if(nullableString ! =null) {
        var nullableStringLength = nullableString.length // An error is reported here!!}}Copy the code

The following error is reported:

Error:(9, 40) Kotlin: Smart cast to 'String' is impossible, because 'nullableString' is a mutable property that could have been changed by this time

So, in Kotlin, the correct short position would look something like this:

fun testNullableString(a) {
    varnullableStringLength = nullableString? .length }Copy the code

Num 5: Kotlin overwrites a method in a Java parent class.

Step 1: The Java parent class defines onDialogCreate with a non-empty parameter: savedInstanceState

// JavaKengBase.java
public class JavaKengBase {
    public void onDialogCreate(Object savedInstanceState) {
        // todo nothings}}Copy the code

Step 2: Kotlin inherits and overwrites JavaKengBase

class Keng : JavaKengBase() {
    override fun onDialogCreate(savedInstanceState: Any) {// Note: here, is Any, not Any?
        super.onDialogCreate(savedInstanceState)
    }
}
Copy the code

Step 3: Use Java polymorphism to call onDialogCreate and pass in the NULL argument

public class KengJava {
    public static void main(String[] args) {
        JavaKengBase keng = new Keng();
        keng.onDialogCreate(null);// Note: null argument}}Copy the code

There can be two questions here:

The first:"overrides nothing"

The reason is in the onDialogCreate(savedInstanceState: Any) method definition: Any, not Any? On.

Note: Don’t trust the AS compiler. Override Method is still a Nullable parameter.

Error:(17, 5) Kotlin: 'onDialogCreate' overrides nothing

The second: IllegalArgumentException: Parameter specified as non – null is null

Parameter Specified as non-null is null may be thrown at runtime, even if compiled. This exception is a very common exception in mixed Java and Kotlin development.

To sum up: the above problem is very easy to solve, just need to add a method parameter after? Can.

override fun onDialogCreate(savedInstanceState: Any?). 
Copy the code

Num 6: Kotlin get up, evenTODOAll of them!

The following bland TODO() throws a RuntimeException!

fun testTodo(a): Unit {
    TODO()
}
Copy the code

This error is: kotlin. NotImplementedError: An operation is not implemented., let’s take a look at the TODO () :

public inline fun TODO(): Nothing = throw NotImplementedError()
Copy the code

Num 7:is,asIn the pit

After obj is String, in the scope, the type has been converted, kind of like Java polymorphism.

fun testAsIs(a) {
  var obj: Any? = null

  if (obj is String) {// The scope in the method body, obj, is String
      var length = obj.length
  }
}
Copy the code

TypeCastException: NULL cannot be cast to non-null type kotlin.string

Var strAble1 = text as String? Var strAble2 = text as String?Copy the code

The recommended way to write as:

// If the conversion fails, it is automatically converted to an empty object
var strAble = text as? String
Copy the code

Num 8: Kotlin’s understanding of Property

In Kotlin, a property with or without a backing field is called a property. In Java, the field + GET and set methods are a property.

var age = 0
    set(value){
        age = value + 1
    }
Copy the code

This is actually going to recurse and not succeed.

They will not make the wheels again before pearls and jade. For extra interest, enter the portal: Howshea understands properties in Kotlin


Since the pitfalls of practice always come with best practices, here are a few best practices for readers:

Num 1:alsoKeywords, best practices:

while(bufferReader.readLine().also({ line = it }) ! =null) {
	// do something
}
Copy the code

Equivalent to Java:

while ((line = bufferReader.readLine()) ! = null) { // do something }Copy the code

Num 2:takeIfKeywords, best practices:

/ / the original code
if(someObject ! =null && status) {
   doThis()
}

Best practicessomeObject? .takeIf{ status }? .apply{ doThis() }Copy the code

Num 3: singleton mode

As for the design pattern writing, the beads are in the first place, again do not duplicate the wheel, portal: Kotlin’s 5 singletons versus Java.

Public class Singleton {private volatile static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance==null){ synchronized (Singleton.class){ if(instance==null){ instance=new Singleton(); } } } return instance; } // Kotlin implements class Singleton private constructor() {companion object {val instance: Singleton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { Singleton() } } }Copy the code

Here: Pay attention to the use of the lazy keyword in the double check lock implementation. portal