Java 面向对象/Java 接口
本地内部类是在块内定义的内部类。一般来说,这个块是一个方法体。有时这个块可以是一个for循环,或者一个if子句。本地内部类不是任何封闭类的成员。它们属于它们在其中定义的块,由于其中的本地内部类不能具有与它们相关联的任何访问修饰符。但是,它们可以被标记为最终或抽象。这些类可以访问包含它的类的字段。本地内部类必须在它们定义的块中实例化。
局部内部类的规则:
本地内部类的范围仅限于它们在其中定义的块。
本地内部类无法从其创建块的外部实例化。
在JDK 7中,本地内部类只能访问封闭块的最终本地变量。但是,从JDK 8开始,可以在本地内部类中访问封闭块的非最终局部变量。
一个本地类可以访问其封闭类的成员。
本地内部类可以扩展抽象类,也可以实现接口。
声明本地内部类:可以在块内声明本地内部类。该块可以是方法体,初始化块,循环或甚至是if语句。
访问成员:本地内部类可以访问封闭它的类的字段以及在其中定义的块的字段。但是,只有在这些类被声明为final或最终有效时,才可以访问包含它的块的变量或参数。一旦初始化后其值不变的变量被称为有效最终变量。在方法体内定义的本地内部类可以访问它的参数。
在编译时会发生什么?
当编译包含本地内部类的程序时,编译器将生成两个.class文件,一个用于外部类,另一个用于内部类,它具有对外部类的引用。这两个文件由编译器命名为:
Outer.class
Outer$1Inner.class
方法体内的声明
// 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();
}
}
输出:
Divisor = 4
Remainder = 0
Inside inner class
Quotient = 5
注意: - 本地类可以访问实际最终的封闭块的本地变量和参数。例如,如果您添加高亮显示的赋值语句中的内部类的构造函数或以任何方法内部在上面的例子类:
public Inner()
{
sum = 50;
divisor= 4;
remainder=sum%divisor;
}
由于这个赋值语句,变量和不再有效。因此,Java编译器会生成类似于“从内部类引用的局部变量必须是最终或有效最终”的错误消息。
在if语句中声明
// 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 code to demonstrate that inner
// classes cannot be declared as static
publicclassOuter
{
privateintgetValue(intdata)
{
staticclassInner
{
privateintgetData()
{
System.out.println("Inside inner class");
if(data < 10)
{
return5;
}
else
{
return15;
}
}
}
Inner inner = newInner();
returninner.getData();
}
publicstaticvoidmain(String[] args)
{
Outer outer = newOuter();
System.out.println(outer.getValue(10));
}
}
输出:
Compilation error
说明:上述程序导致编译错误,因为内部类不能声明
为静态。内部类与它们在内部定义的块相关联,而不与外部类相关联(在这种情况下为外部)。
// Java code to demonstrate
// the scope of inner class
publicclassOuter
{
privatevoidmyMethod()
{
classInner
{
privatevoidinnerMethod()
{
System.out.println("Inside inner class");
}
}
}
publicstaticvoidmain(String[] args)
{
Outer outer = newOuter();
Inner inner = newInner();
System.out.println(inner.innerMethod());
}
}
输出:
Compilation error
说明:上面的程序会导致编译错误,因为内部类的范围仅限于它们在其中定义的块。