【问题标题】:Local inner class in JavaJava中的本地内部类
【发布时间】:2026-01-14 10:55:01
【问题描述】:

对于下面的代码示例,当我们执行代码时会打印:

来自实例方法
来自本地内部类

现在,如果我只想执行本地内部类方法 m2() 并希望输出为:

来自本地内部类

class A {
    void m1() {
        class B {
            void m2() {
                System.out.println("from local inner class");
            }
        }
        System.out.println("from instance method");
        B b = new B();
        b.m2();
    }

    public static void main(String[] args) {
        A a = new A();
        a.m1();
    }
}

当绝对需要本地内部类时,具体的用例是什么,如果没有它,某些功能可能无法实现。

【问题讨论】:

  • 如果你只想执行一个println 那么... err... 删除另一个?
  • 我在想,有没有办法只执行 m2() ?
  • 方法本地的想法是它应该只在该方法中使用。因此,如果您想从外部m1 调用m2,为什么要将B 本地化为m1
  • “我想知道,有没有办法只执行 m2() ?”从技术上讲,是的。你可以让m1返回ObjectB,然后使用反射在m1之外调用m2,我想。
  • m2 在 m1 方法之外不可见。只执行 m2 向 m1 方法添加一个布尔参数并使用 if 语句来决定是只需要执行 m2 还是整个 m1

标签: java inner-classes


【解决方案1】:

我看不到您在做什么,也许您想将方法的创建与方法的调用分开,将所有实现细节隐藏在内部类中?如果是这样,那该怎么办……

首先创建一个接口,这样你就知道你正在访问什么类型(比反射更简洁)

interface X {
    void m2()
}

现在方法 m1() 返回一个实现接口的类的实例

class A {
    X m1() {
        class B {
            void m2() {
                System.out.println("from local inner class");
            }
        }
        B b = new B();
        return b;
    }

    public static void main(String[] args) {
        A a = new A();
        // call m1() to get an instance of interface X
        X x = a.m1();
        // invoke method on interface instance
        x.m2()
    }
}

这将方法的创建(包装在一个类中,认为是“函子”)与方法的调用分开。

【讨论】:

    【解决方案2】:

    您可以从函数返回本地类类型的对象并通过反射调用它们的方法,例如以下作品:

    class A {
        Object m1() {
            class B {
                public void m2() {
                    System.out.println("from local inner class");
                }
            }
            System.out.println("from instance method");
            B b = new B();
            b.m2();
            return b;
        }
    
        public static void main(String[] args) {
            try {
                A a = new A();
                Object obj = a.m1();
                obj.getClass().getMethod("m2").invoke(obj);
            } catch (Exception e) {
                System.out.println(e.toString());   
            }   
        }
    }
    

    你应该这样做吗?应该不会吧。

    【讨论】: