During development, we may become accustomed to some of the features of a programming language for reasons of habit, especially if we use only one language for daily development. However, when you develop in more than one language, even though they are high-level languages, there are many features that differ from one another.

The phenomenon of description

Prior to Java 8, anonymous inner classes used external members Cannot refer to a non-final variable arg inside an inner class defined ina different method



But after Java 8, similar scenarios are no longer prompted:



Can such variables be changed at will? Of course not, you will still get an error when you try to modify these variables:



As you can see, when trying to modify a variable of the base data type, Varible ‘num’ is email exchange from within inner class, need to be final or effectively final. Kotlin, by contrast, has no such limit:



Cause analysis,

It’s hard to see why on the surface, but look what the compiler does! Several.class files are generated after running the javac command:



The TestInnerClass$1.class is the compiled file of the anonymous inner class.

class TestInnerClassThe $1 extends InnerClass {
    TestInnerClassThe $1(TestInnerClass var1, int var2, DataBean var3) {
        super(var1);
        this.this$0 = var1;
        this.val$num = var2;
        this.val$bean = var3;
    }

    void doSomething() {
        super.doSomething();
        System.out.println("num = " + this.val$num);
        System.out.println("bean name is: " + this.val$bean.name); }}Copy the code

It turns out that the anonymous inner class is treated like a normal class, except that when the compiler generates its constructor, it passes in a reference to the outer class as well as a copy of the variables of the base datatype and a reference to the variables of the datatype. Therefore, the variables of the primitive data type cannot be modified, otherwise they will be inconsistent with the external variables, and the passing of the variables will become meaningless.

In addition to preventing classes from being inherited, the final keyword prevents even variables from being reassigned.

Scene contrast

But why is it possible for Kotlin to modify the value of a primitive data type directly in an anonymous inner class? See what Kotlin compiled and decompiled back:

   public final void useNestedClass(@NotNull final TestNestedClass.DataBean bean) {
      Intrinsics.checkParameterIsNotNull(bean, "bean"); final IntRef num = new IntRef(); //---1 num.element = 1; //---2 String var3 ="before action, num = " + num.element;
      System.out.println(var3);
      <undefinedtype> nestedClass = new TestNestedClass.NestedClass() {
         public void doSomething() { num.element = 678; //---3 bean.setName("xyz");
            String var1 = "num = " + num.element;
            System.out.println(var1);
            var1 = "bean name is: "+ bean.getName(); System.out.println(var1); }}; nestedClass.doSomething(); String var4 ="after action, num = "+ num.element; //---4 System.out.println(var4); }Copy the code

As you can see, when variables of primitive data types need to be passed, the Kotlin compiler wraps the data so that it changes from value to reference, so that internal changes do not of course affect external ones. Verify what the Kotlin compiler does when a variable is not passed:

   public final void useNestedClass(@NotNull TestNestedClass.DataBean bean) {
      Intrinsics.checkParameterIsNotNull(bean, "bean");
      int num = 1;
      String var3 = "before action, num = " + num;
      System.out.println(var3);
      int num = 678;
      var3 = "after action, num = " + num;
      System.out.println(var3);
   }
Copy the code

Ha ha, not to beat a dead horse, thumbs up!

Author: guanpj; Source: http://rrd.me/epfKR



Welcome to follow my wechat public account “Code farming breakthrough”, share Python, Java, big data, machine learning, artificial intelligence and other technologies, pay attention to code farming technology improvement, career breakthrough, thinking transition, 200,000 + code farming growth charge first stop, accompany you have a dream to grow together