📜  Java本地内部类

📅  最后修改于: 2020-04-06 04:33:03             🧑  作者: Mango

本地内部类中的嵌套类是在内部定义的内部类。通常,此块是方法主体。有时此块可以是for循环或if子句。本地内部类不是任何封闭类的成员。它们属于在其内定义的块,因此,本地内部类不能与它们关联任何访问修饰符。但是,它们可以标记为最终的或抽象的。这些类可以访问包含它的类的字段。本地内部类必须在其定义的块中实例化。
本地内部类的规则:

  1. 局部内部类的范围仅限于定义它们的
  2. 本地内部类不能从创建它的外部实例化。
  3. 直到JDK 7,Local内部类只能访问封闭块的最终局部变量。但是,从JDK 8中可以访问局部内部类中封闭块的非最终局部变量。
  4. 本地类可以访问其所在的成员。
  5. 局部内部类可以扩展抽象类,也可以实现接口。



声明本地内部类:可以在块中声明本地内部类。该块可以是方法主体,初始化块,for循环甚至是if语句。
访问成员:本地内部类可以访问封闭它的类的字段以及在其中定义的块的字段。但是,只有在将这些类声明为final时,这些类才能访问封闭该块的变量或参数。初始化后其值不变的变量称为有效最终变量。在方法体内定义的局部内部类可以访问其参数。

编译时会发生什么

编译包含本地内部类的程序时,编译器将生成两个.class文件,一个用于外部类,另一个用于具有对外部类的引用的内部类。这两个文件被编译器命名为:

  • 外部类
  • 外部$ 1

方法主体中的声明

// Java展示局部内部类
public class Outer
{
    private void getValue()
    {

        int sum = 20;
        // 局部内部类在方法内
        class Inner
        {
            public int divisor;
            public int remainder;
            public Inner()
            {
                divisor = 4;
                remainder = sum%divisor;
            }
            private int getDivisor()
            {
                return divisor;
            }
            private int getRemainder()
            {
                return sum%divisor;
            }
            private int getQuotient()
            {
                System.out.println("在内部类");
                return sum / divisor;
            }
        }
        Inner inner = new Inner();
        System.out.println("除数 = "+ inner.getDivisor());
        System.out.println("余数 = " + inner.getRemainder());
        System.out.println("商 = " + inner.getQuotient());
    }
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        outer.getValue();
    }
}

输出:

除数 = 4
余数 = 0
在内部类
商 = 5

注意:本地类可以访问封闭块的局部变量和参数,这些变量和参数实际上是final的。例如,如果你在添加高亮显示的赋值语句内部类的构造函数或以任何方法在上面的例子:

public Inner()
{
       sum = 50;
       divisor = 4;
       remainder = sum%divisor;
}

由于存在此赋值语句,因此变量sum不再有效地为final。结果,Java编译器会生成一条错误消息,类似于“从内部类引用的局部变量必须是最终的或实际上是最终的”。

在if语句中声明

// Java在if内声明内部类
public class Outer
{
    public int data = 10;
    public int getData()
    {
        return data;
    }
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        if(outer.getData() < 20)
        {
            // 在if内的内部类
            class Inner
            {
                public int getValue()
                {
                    System.out.println("在内部类");
                    return outer.data;
                }
            }
            Inner inner = new Inner();
            System.out.println(inner.getValue());
        }
        else
        {
            System.out.println("外部类");
        }
    }
}

输出:

在内部类
10

演示内部类的错误代码

// Java展示内部类不能被声明为static
public class Outer
{
    private int getValue(int data)
    {
        static class Inner
        {
            private int getData()
            {
                System.out.println("内部类");
                if(data < 10)
                {
                    return 5;
                }
                else
                {
                    return 15;
                }
            }
        }
        Inner inner = new Inner();
        return inner.getData();
    }
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        System.out.println(outer.getValue(10));
    }
}

输出:

Compilation error

说明:上面的程序导致编译错误,因为内部类不能声明为静态。内部类与它们在内部定义的块相关联,而不与外部类(在这种情况下为外部)相关联。

// Java展示内部类的范围
public class Outer
{
    private void myMethod()
    {
        class Inner
        {
            private void innerMethod()
            {
                System.out.println("内部类");
            }
        }
    }
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        Inner inner = new Inner();
        System.out.println(inner.innerMethod());
    }
}

输出:

Compilation error

说明:上面的程序导致编译错误,因为内部类的范围仅限于定义它们的块。