匿名内部类访问成员变量和局部变量的优化

Posted 技术无产者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了匿名内部类访问成员变量和局部变量的优化相关的知识,希望对你有一定的参考价值。

准备工具: jad, jdk

测试代码:

public class HigherUser 
    public interface TeacherService1 
        void queryUserInfo();
    

    String str="ad";
    int a=2;
    private String name;
    public static void main(String[] args) 

        HigherUser higherUser=new HigherUser();
        higherUser.f();
    
// 用于测试匿名内部类 访问成员变量
    public void f()
    


        TeacherService1 teacherService=new TeacherService1() 
            @Override
            public void queryUserInfo() 

                System.out.println(a);
                a=3;
                System.out.println(str);
            
        ;
        str="mzd";
        a=4;
        teacherService.queryUserInfo();
        System.out.println(a);

    

//用于测试匿名内部类访问局部变量
    public static void test( int x) 
        Runnable runnable = new Runnable()
         @Override public void run() 
            System.out.println("ok:" + x);
        ;
    


// res:

4
mzd
3
由这个结果可以看到 在匿名内部类修改成员变量时,可以直接作用到原对象,下面分析具体的原因

javac ./ HighUser.java 就会生成图片中 .class结尾的文件,.jad文件不用看,不是javac生成的

 1.访问成员变量

1>先看HigherUser$1.class文件

它是为TeacheerService1接口生成的实现类,访问a和str变量都是通过 this$0这个对象来访问的,而这个对象是通过构造函数传过来的,但这个class文件并没有显式这个变量的定义,那么我们接下来用jad生成对应的.java文件来看

import test.HigherUser.TeacherService1;

class HigherUser$1 implements TeacherService1 
    HigherUser$1(HigherUser var1) 
        this.this$0 = var1;
    

    public void queryUserInfo() 
        System.out.println(this.this$0.a);
        this.this$0.a = 3;
        System.out.println(this.this$0.str);
    

2>jad生成.java文件

 看看下面的文件就清楚明白了,上面的this$0就是调用这个匿名内部类的对象,所以这里在匿名内部类中修改变量的值可以直接作用到原对象的成员变量。

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   HigherUser.java

package test;

import java.io.PrintStream;

// Referenced classes of package test:
//            HigherUser

class HigherUser$1
    implements acherService1


    public void queryUserInfo()
    
        System.out.println(a);
        a = 3;
        System.out.println(str);
    

    final HigherUser this$0;

    HigherUser$1()
    
        this$0 = HigherUser.this;
        super();
    

2.访问局部变量

这个就比较简单,它对应的是HigherUser$2 文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package test;

final class HigherUser$2 implements Runnable 
    HigherUser$2(int var1) 
        this.val$x = var1;
    

    public void run() 
        System.out.println("ok:" + this.val$x);
    

jad编译:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   HigherUser.java

package test;

import java.io.PrintStream;

// Referenced classes of package test:
//            HigherUser

static class HigherUser$2
    implements Runnable


    public void run()
    
        System.out.println((new StringBuilder()).append("ok:").append(val$x).toString());
    

    final int val$x;

    HigherUser$2(int i)
    
        val$x = i;
        super();
    

看看idea中显式的.class文件也就是:

 public static void test(final int x) 
        Runnable var10000 = new Runnable() 
            public void run() 
                System.out.println("ok:" + x);
            
        ;
    

很多文章都讲过这点,是把局部变量加上final修饰当参数传递到新生成的类中,不能进行修改

     这篇文章主要 是用来了解匿名内部类怎么访问成员变量的,网上没有见到能说清楚的文章,这里测试后做以梳理。

以上是关于匿名内部类访问成员变量和局部变量的优化的主要内容,如果未能解决你的问题,请参考以下文章

匿名内部类访问成员变量和局部变量的优化

为什么匿名内部类和内部类只能访问final局部变量

java 匿名内部类

匿名内部类不能访问外部类方法中的局部变量,除非变量被声明为final类型

为啥内部类的private变量可被外部类直接访问

第6题-为什么局部内部类和匿名内部类只能访问局部final变量