您当前的位置: 首页 >  面试
  • 0浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

面试:内部类为什么会持有外部类的引用

沙漠一只雕得儿得儿 发布时间:2021-12-17 17:13:16 ,浏览量:0

问题1:内部类为什么会持有外部类的引用

这是因为内部类虽然和外部类写在同一个文件中,但是编译后还是会生成不同的class文件,其中内部类的构造函数中会传入外部类的实例,然后就可以通过this$0访问外部类的成员。

其实也挺好理解的吧,因为在内部类中可以调用外部类的方法,变量等等,所以肯定会持有外部类的引用的。

贴一段内部类在编译后用JD-GUI查看的class代码,也许你能更好的理解:

//原代码
class InnerClassOutClass{

    class InnerUser {
       private int age = 20;
    }
}

//class代码
class InnerClassOutClass$InnerUser {
    private int age;
    InnerClassOutClass$InnerUser(InnerClassOutClass var1) {
        this.this$0 = var1;
        this.age = 20;
     }
}
问题2:kotlin中的内部类与Java有什么不一样吗 这是因为在kotlin中的匿名内部类分为两种情况:
  • 在Kotlin中,匿名内部类如果没有使用到外部类的对象引用时候,是不会持有外部类的对象引用的,此时的匿名内部类其实就是个静态匿名内部类,也就不会发生内存泄漏。
  • 在Kotlin中,匿名内部类如果使用了对外部类的引用,像我刚才使用了btn2,这时候就会持有外部类的引用了,就会需要考虑内存泄漏的问题。
//java,匿名内部类的写法
btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {

    }
});

 上面这个是java匿名内部类的写法,kotlin没有new关键字,那么kotlin的匿名内部类该怎么写呢?

btn.setOnClickListener(object : View.OnClickListener{
    override fun onClick(v: View?) {
        print("1111")
    }
})
同样kotlin中对于内部类也是和Java有区别的:
  • Kotlin中所有的内部类都是默认静态的,也就都是静态内部类
  • 如果需要调用外部的对象方法,就需要用inner修饰,改成和Java一样的内部类,并且会持有外部类的引用,需要考虑内存泄漏问题。

kotlin的内部类与java的内部类有点不同java的内部类可以直接访问外部类的成员,kotlin的内部类不能直接访问外部类的成员,必须用inner标记之后才能访问外部类的成员 

  • 没有使用inner标记的内部类
class A{
    var a = 0
    class B{
        //B类的内部是不能直接用a变量的
        var b = 1
    }
}
  •  用inner标记的内部类
class A{
    var a = 0
    inner class B{
        //B类的内部可以直接用a变量
        var b = a
    }
}

反编译后的java代码

public final class A {
   private int a;

   public final int getA() {
      return this.a;
   }

   public final void setA(int var1) {
      this.a = var1;
   }

   public final class B {
      private int b = A.this.getA();

      public final int getB() {
         return this.b;
      }

      public final void setB(int var1) {
         this.b = var1;
      }
   }
}

从上面可以看出,没有使用inner标记的内部类最后生成的是静态内部类,而使用inner标记的生成的是非静态内部类。

关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.0371s