代码之家  ›  专栏  ›  技术社区  ›  mr debug

静态嵌套类匿名方法java中访问外部类变量的最佳实践

  •  -2
  • mr debug  · 技术社区  · 8 年前

    在基于android的应用程序中,我有一个匿名函数,即 onClick Listener 在我的静电里 InnerClass OuterClass ……问题是,当我试图从所需位置访问特定视图时,它指出不能从静态角度访问非静态成员…当我从外环线静止的角度看时,它是有效的,但是这是一个好的实践吗?它不会导致任何类型的内存泄漏吗?在那种情况下能做什么?

    public class OuterClass extends CustomAppCompatActiivity {
    static EditText city_et;
     public static class InnerClass extends DialogFragment {
     @Override
            public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
                okBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                            //the view to access
                            city_et.setText("");
    
                        }
                        getDialog().dismiss();
                    }
                });
            }
    
     }
    
    
    }
    
    2 回复  |  直到 8 年前
        1
  •  0
  •   Jai    8 年前

    静态嵌套类 InnerClass 无法访问封闭实例的成员,因为 内类 可能不属于 OuterClass . 想象一下:

    public class Outer {
        public String out = "out";
    
        public static class StaticInner {
            public void printEnclosing() {
                System.out.println(Outer.this.out); // Let's say this compiles
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            StaticInner si = new StaticInner();
            si.printEnclosing();
        }
    }
    

    注意 Outer 从未被创造过。那么如何打印 out 是吗?

    你需要的是内在的阶级。除了封闭类或其子类之外,任何人都不能实例化内部类。这可以确保只有在已经存在外部类的实例时才能实例化内部类。

    public class Outer {
        public String out = "out";
        public Inner inner = new Inner();
    
        public class Inner {   
            public void printEnclosing() {
                System.out.println(Outer.this.out); // "out" can be safely referenced
            }
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Inner inner = new Inner(); // Compile-time error
    
            Outer out = new Outer();
            out.inner.printEnclosing(); // This works, because you are calling method of the Inner class instance owned by Outer class.
        }
    }
    

    因此,您的代码应该是这样的:

    public class OuterClass extends CustomAppCompatActiivity {
        private EditText city_et;
        private final InnerClass inner = new InnerClass();
        public class InnerClass extends DialogFragment {
            @Override
            public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
                okBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //the view to access
                        city_et.setText("");
    
                        getDialog().dismiss();
                    }
                });
            }
        }
    
        public InnerClass getInnerClass() {
            return inner;
        }
    }
    

    更新

    关于你对内存泄漏的关注,我想问题是:什么是 内类 外环 是的。每次你能创造一个 内类 实例(或 内类 当你有一个新的 外环 . 内类 需要参考 外环 为了打电话 setText() .

    因此,本合同为: 内类 离不开 外环 ,和 内类 总是有一个 内类 . 内类 将与 外环 是的。

    如果 内类 外环 是吗 内类 可以在没有 外环 ,你所需要的就是 EditText city_et 引用,那么您应该传入该引用。自从 内类 独立于 外环 现在,您可以使用静态嵌套类,或者简单地将其移动到另一个单独的类。

    public class OuterClass extends CustomAppCompatActiivity {
        private EditText city_et;
    
        public static class InnerClass extends DialogFragment {
            private EditText city_et;
    
            public InnerClass(EditText city_et) { // Pass a reference in
                this.city_et = city_et;
            }
    
            @Override
            public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
                okBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        //the view to access
                        city_et.setText("");
    
                        getDialog().dismiss();
                    }
                });
            }
        }
    }
    

    这边,一个 外环 实例可以在任何时候进行垃圾回收,而不依赖于 内类 是的。唯一不能垃圾收集的引用是 EditText 实例。

    更新2

    ejp指出,“除了封闭类或其子类之外,任何人都不能实例化内部类”是错误的,并且在签出之后,他是对的。除此之外,术语“内部类”是“非静态嵌套类”的正式术语。

    但是,如果您认为 DialogFragment 子类的生存时间可能比封闭类长。

        2
  •  0
  •   Thiyagu    8 年前

    不了解全部情况很难回答。很可能 EditText city_et 不是 静止的 只为了编译代码。(是否所有实例 OuterClass 也一样 city_et -我不这么认为)。

    你可以通过 城市 作为 RecyclerDialogFragment 构造函数并将其存储为实例变量,这样就有了静态嵌套类而不是内部类。