📜  Java中的本地内部类

📅  最后修改于: 2022-05-13 01:54:36.197000             🧑  作者: Mango

Java中的本地内部类

先决条件: Java中的嵌套类

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

本地内部类规则:

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

Java中的局部内部类

声明本地内部类:可以在块内声明本地内部类。此块可以是方法体、初始化块、for 循环,甚至是 if 语句。

访问成员:本地内部类可以访问包含它的类的字段以及定义它的块的字段。但是,这些类只有在声明为 final 或实际上是 final 时才能访问包含它的块的变量或参数。初始化后值不变的变量称为有效的最终变量。在方法体内定义的本地内部类可以访问其参数。

编译时会发生什么?

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

  • 外部类
  • 外部$1Inner.class

方法体内的声明

Java
// Java program to illustrate
// working of local inner classes
 
public class Outer
{
    private void getValue()
    {
        // Note that local variable(sum) must be final till JDK 7
        // hence this code will work only in JDK 8
        int sum = 20;
         
        // Local inner Class inside method
        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("Inside inner class");
                return sum / divisor;
            }
        }
         
        Inner inner = new Inner();
        System.out.println("Divisor = "+ inner.getDivisor());
        System.out.println("Remainder = " + inner.getRemainder());
        System.out.println("Quotient = " + inner.getQuotient());
    }
     
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        outer.getValue();
    }
}


Java
// Java program to illustrate Declaration of
// local inner classes inside an if statement
 
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)
        {
            // Local inner class inside if clause
            class Inner
            {
                public int getValue()
                {
                    System.out.println("Inside Inner class");
                    return outer.data;
                }
            }
 
            Inner inner = new Inner();
            System.out.println(inner.getValue());
        }
        else
        {
            System.out.println("Inside Outer class");
        }
    }
}


Java
// Java code to demonstrate that inner
// classes cannot be declared as static
 
public class Outer
{
    private int getValue(int data)
    {
        static class Inner
        {
            private int getData()
            {
                System.out.println("Inside inner class");
                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));
    }
}


Java
// Java code to demonstrate
// the scope of inner class
 
public class Outer
{
    private void myMethod()
    {
        class Inner
        {
            private void innerMethod()
            {
                System.out.println("Inside inner class");
            }
        }
    }
     
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        Inner inner = new Inner();
        System.out.println(inner.innerMethod());
    }
}


输出
Divisor = 4
Remainder = 0
Inside inner class
Quotient = 5

例如,如果在上例中的Inner类构造函数或Inner类的任何方法中添加突出显示的赋值语句:

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

由于这个赋值语句,变量sum不再是有效的 final了。因此, Java编译器会生成类似于“从内部类引用的局部变量必须是最终的或有效的最终”的错误消息。

if 语句中的声明

Java

// Java program to illustrate Declaration of
// local inner classes inside an if statement
 
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)
        {
            // Local inner class inside if clause
            class Inner
            {
                public int getValue()
                {
                    System.out.println("Inside Inner class");
                    return outer.data;
                }
            }
 
            Inner inner = new Inner();
            System.out.println(inner.getValue());
        }
        else
        {
            System.out.println("Inside Outer class");
        }
    }
}
输出
Inside Inner class
10

演示内部类的错误代码

Java

// Java code to demonstrate that inner
// classes cannot be declared as static
 
public class Outer
{
    private int getValue(int data)
    {
        static class Inner
        {
            private int getData()
            {
                System.out.println("Inside inner class");
                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

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

Java

// Java code to demonstrate
// the scope of inner class
 
public class Outer
{
    private void myMethod()
    {
        class Inner
        {
            private void innerMethod()
            {
                System.out.println("Inside inner class");
            }
        }
    }
     
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        Inner inner = new Inner();
        System.out.println(inner.innerMethod());
    }
}

输出

prog.java:20: error: cannot find symbol
        Inner inner = new Inner();
        ^
  symbol:   class Inner
  location: class Outer

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