匿名内部类无法访问修改外部参数怎么办

很多时候,比如你在写一个static方法,我们需要在匿名内部类里修改外部参数,但是这时候编译器就会爆红了,告诉你这不可取。
这是这么回事呢?
1 这里所说的“匿名内部类”主要是指在其外部类的成员方法内定义,同时完成实例化的类,若其访问该成员方法中的局部变量,局部变量必须要被final修饰。
2 原因是编译程序实现上的困难:内部类对象的生命周期会超过局部变量的生命周期。局部变量的生命周期:当该方法被调用时,该方法中的局部变量在栈中被创建,当方法调用结束时,退栈,这些局部变量全部死亡。而内部类对象生命周期与其它类一样:自创建一个匿名内部类对象,系统为该对象分配内存,直到没有引用变量指向分配给该对象的内存,它才会死亡(被JVM垃圾回收)。所以完全可能出现的一种情况是:成员方法已调用结束,局部变量已死亡,但匿名内部类的对象仍然活着。
3 如果匿名内部类的对象访问了同一个方法中的局部变量,就要求只要匿名内部类对象还活着,那么栈中的那些它要所访问的局部变量就不能“死亡”。
4 解决方法:匿名内部类对象可以访问同一个方法中被定义为final类型的局部变量。定义为final后,编译程序的实现方法:对于匿名内部类对象要访问的所有final类型局部变量,都拷贝成为该对象中的一个数据成员。这样,即使栈中局部变量已死亡,但被定义为final类型的局部变量的值永远不变,因而匿名内部类对象在局部变量死亡后,照样可以访问final类型的局部变量,因为它自己拷贝了一份,且与原局部变量的值始终一致。
这里参考了
java8 如果你使用了局部变量的话 会默认会final
这里的解释参考了
https://blog.csdn.net/zhangsir001/article/details/103229812

但是 有的时候,你又需要匿名内部类去通知修改参数那怎么办???
1.把变量设置成final数组成员 在你需要使用变量的位置直接使用对应地址,由于final数组是指数组的引用,所以可以这么用
final String[] completeExplain = new String[2];
completeExplain[0] = null;

其实使用callback 传入回调即可 比如

private static void initWeight(String id,ActionCallback callback) {
                OkHttpUtils
                .get(NewBaseUrl.product_inf + id)
                .headers("token", ViewUtil.getSpByName("token"))
//                    .params("selectIds", getIntent().getStringExtra("id"))
                .params("page", "1")
                .params("limit", "100")
                .execute(new StringCallback() {
                    @Override
                    public void onResponse(boolean isFromCache, String result, Request request, @Nullable Response response) {
                        Log.i("test",   "获取产品详情: " + result);
                        JSONObject jsonObj = JSON.parseObject(result);
                        int code = jsonObj.getInteger("code");
                        JSONObject Jpage = jsonObj.getJSONObject("page");
                        if (code == 0) {
                            ProductEntity bean = (ProductEntity) JsonExcludeNull.parseClassExcludeNull(jsonObj.getString("product"), ProductEntity.class);
                            if (bean.getOperateMappingValues()!=null){
                                  callback.run(bean.getOperateMappingValues());
                            }

//                            initView();
                        } else {
                            ToastUtil.error( jsonObj.getString("msg"));

                        }

                    }
                });
    }

在主方法里,处理需要变化的参数也就是

  initWeight(id, new ActionCallback() {
                @Override
                public void run() {

                }

                @Override
                public void run(Object o) {
                    listW.clear();
                    listW.addAll((Collection) o);
                    adapter3.notifyDataSetChanged();
                }
            });

在贴一下callback的类

public interface ActionCallback {
    void run();

    default void run(ItemListBean bean, Dialog dialog) {
    }
    default void run(Object o, Dialog dialog) {
    }
    default void run(Object o) {
    }
    default void run(boolean b) {

    }

    default void run(int position) {

    }

    default void run(TreeNode node) {

    }

    ;

}

你可能感兴趣的:(匿名内部类无法访问修改外部参数怎么办)