Java基础-方法内部类

133 阅读3分钟

方法内部类

内部类还可以定义在一个方法体中。我们看个例子,如代码清单5-7所示。

代码清单5-7 方法内部类示例

public class Outer {

    private int a = 100;

    public void test(final int param){

        final String str = "hello";

        class Inner {

            public void innerMethod(){

                System.out.println("outer a " +a);

                System.out.println("param " +param);

                System.out.println("local var " +str);

            }

        }

        Inner inner = new Inner();

        inner.innerMethod();

    }

}

类Inner定义在外部类方法test中,方法内部类只能在定义的方法内被使用。如果方法是实例方法,则除了静态变量和方法,内部类还可以直接访问外部类的实例变量和方法,如innerMethod直接访问了外部私有实例变量a。如果方法是静态方法,则方法内部类只能访问外部类的静态变量和方法。方法内部类还可以直接访问方法的参数和方法中的局部变量,不过,这些变量必须被声明为final,如innerMethod直接访问了方法参数param和局部变量str。

方法内部类是怎么实现的呢?对于代码清单5-7,系统生成的两个类代码大概如代码清单5-8所示。

代码清单5-8 方法内部类示例的内部实现

public class Outer {

    private int a = 100;

    public void test(final int param) {

        final String str = "hello";

        OuterInner inner = new OuterInner(this, param);

        inner.innerMethod();

    }

    static int access$0(Outer outer){

        return outer.a;

    }

}

public class OuterInner {

    Outer outer;

    int param;

    OuterInner(Outer outer, int param){

        this.outer = outer;

        this.param = param;

    }

    public void innerMethod() {

        System.out.println("outer a " + Outer.access$0(this.outer));

        System.out.println("param " + param);

        System.out.println("local var " + "hello");

    }

}

与成员内部类类似,OuterInner类也有一个实例变量outer指向外部对象,在构造方法中被初始化,对外部私有实例变量的访问也是通过Outer添加的方法access$0来进行的。

方法内部类可以访问方法中的参数和局部变量,这是通过在构造方法中传递参数来实现的,如OuterInner构造方法中有参数int param,在新建OuterInner对象时,Outer类将方法中的参数传递给了内部类,如OuterInner inner=new OuterInner(this,param);。在上面的代码中,String str并没有被作为参数传递,这是因为它被定义为了常量,在生成的代码中,可以直接使用它的值。

这也解释了为什么方法内部类访问外部方法中的参数和局部变量时,这些变量必须被声明为final,因为实际上,方法内部类操作的并不是外部的变量,而是它自己的实例变量,

只是这些变量的值和外部一样,对这些变量赋值,并不会改变外部的值,为避免混淆,所以干脆强制规定必须声明为final。

如果的确需要修改外部的变量,那么可以将变量改为只含该变量的数组,修改数组中的值,如代码清单5-9所示。

代码清单5-9 方法内部类修改外部变量实例

public class Outer {

    public void test(){

        final String[] str = new String[]{"hello"};

        class Inner {

            public void innerMethod(){

                str[0] = "hello world";

            }

        }

        Inner inner = new Inner();

        inner.innerMethod();

        System.out.println(str[0]);

    }

}

str是一个只含一个元素的数组,方法内部类不能修改str本身,但可以修改它的数组元素。

通过前面介绍的语法和原理可以看出,方法内部类可以用成员内部类代替,至于方法参数,也可以作为参数传递给成员内部类。不过,如果类只在某个方法内被使用,使用方法内部类,可以实现更好的封装。 []www.bilibili.com/video/BV13G…