javaSE_8系列博客——Java语言的特性(三)--类和对象(17)--嵌套类(本地/局部类)
来源:互联网 发布:数据库 null 编辑:程序博客网 时间:2024/05/18 00:43
本地(局部)类是在块中定义的类,它是花括号之间的一组零个或多个语句。你通常会发现方法体中定义的局部类。
声明一个局部类
您可以在任何块中定义一个局部类(有关详细信息,请参阅表达式,语句和块)。例如,您可以在方法体,for循环或if子句中定义局部类。 以下示例LocalClassExample验证两个电话号码。它在方法validatePhoneNumber中定义局部类PhoneNumber:
public class LocalClassExample { static String regularExpression = "[^0-9]"; public static void validatePhoneNumber( String phoneNumber1, String phoneNumber2) { final int numberLength = 10; // Valid in JDK 8 and later: // int numberLength = 10; class PhoneNumber { String formattedPhoneNumber = null; PhoneNumber(String phoneNumber){ // numberLength = 7; String currentNumber = phoneNumber.replaceAll( regularExpression, ""); if (currentNumber.length() == numberLength) formattedPhoneNumber = currentNumber; else formattedPhoneNumber = null; } public String getNumber() { return formattedPhoneNumber; } // Valid in JDK 8 and later:// public void printOriginalNumbers() {// System.out.println("Original numbers are " + phoneNumber1 +// " and " + phoneNumber2);// } } PhoneNumber myNumber1 = new PhoneNumber(phoneNumber1); PhoneNumber myNumber2 = new PhoneNumber(phoneNumber2); // Valid in JDK 8 and later:// myNumber1.printOriginalNumbers(); if (myNumber1.getNumber() == null) System.out.println("First number is invalid"); else System.out.println("First number is " + myNumber1.getNumber()); if (myNumber2.getNumber() == null) System.out.println("Second number is invalid"); else System.out.println("Second number is " + myNumber2.getNumber()); } public static void main(String... args) { validatePhoneNumber("123-456-7890", "456-7890"); }}
该示例通过首先从电话号码除去数字0到9之外的所有字符来验证电话号码。之后,它检查电话号码是否包含正好十位数字(北美电话号码的长度)。此示例打印以下内容:
First number is 1234567890Second number is invalid
访问封闭类中的成员
局部类可以访问其封闭类的成员。在前面的例子中,PhoneNumber构造函数访问成员LocalClassExample.regularExpression。 另外,局部类可以访问局部变量。但是,局部类只能访问被声明为final的局部变量。当局部类访问包围块的局部变量或参数时,它会捕获该变量或参数。例如,PhoneNumber构造函数可以访问局部变量numberLength,因为它被声明为final; numberLength是一个捕获的变量。 然而,从Java SE 8开始,局部类可以访问最终或有效最终的封闭块的局部变量和参数。其值在初始化后永远不会更改的变量或参数是最终的。例如,假设变量numberLength没有声明为final,并且在PhoneNumber构造函数中添加突出显示的赋值语句:
PhoneNumber(String phoneNumber) { numberLength = 7; String currentNumber = phoneNumber.replaceAll( regularExpression, ""); if (currentNumber.length() == numberLength) formattedPhoneNumber = currentNumber; else formattedPhoneNumber = null;}
由于这个赋值语句,变量numberLength不再是有效的final。因此,Java编译器会生成类似于“内部类引用的局部变量必须是final或有效的final”的错误消息,内部类PhoneNumber将尝试访问numberLength变量:
if (currentNumber.length() == numberLength)
从Java SE 8开始,如果您在方法中声明局部类,则可以访问该方法的参数。例如,您可以在PhoneNumber局部类中定义以下方法:
public void printOriginalNumbers() { System.out.println("Original numbers are " + phoneNumber1 + " and " + phoneNumber2);}
局部类的printOriginalNumbers方法访问封闭类中方法validatePhoneNumber的参数phoneNumber1和phoneNumber2。
局部类和内部类的关系
局部类与内部类类似,因为它们不能定义或声明任何静态成员。静态方法中的局部类(如静态方法validatePhoneNumber中定义的PhoneNumber类)只能引用封闭类的静态成员。
例如,如果没有将成员变量regularExpression定义为static,则Java编译器会生成类似于“静态上下文不能引用非静态变量regularExpression”的错误。局部类是非静态的,因为它们可以访问封闭块的实例成员。因此,它们不能包含大多数种类的静态声明。
您不能在块内声明一个接口 ; 接口本质上是静态的。例如,以下代码片段不编译,因为接口HelloThere是在方法body中定义的内容greetInEnglish:
public void greetInEnglish() { interface HelloThere { public void greet(); } class EnglishHelloThere implements HelloThere { public void greet() { System.out.println("Hello " + name); } } HelloThere myGreeting = new EnglishHelloThere(); myGreeting.greet(); }
您不能在局部类中声明静态初始化程序或成员接口。以下代码片段不编译,因为方法EnglishGoodbye.sayGoodbye被声明为静态的。编译器生成类似于“modifier ”的错误,当遇到此方法定义时,静态“仅允许在常量变量声明中”:
public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static void sayGoodbye() { System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); }
局部类可以具有静态成员,只要它们是常量变量。 (一个常量变量是一个原始类型或类型的字符串,它被声明为final,并使用编译时常量表达式初始化。编译时常量表达式通常是一个字符串或算术表达式,可以在编译时进行评估计算。)以下代码片段可以正常编译,因为静态成员EnglishGoodbye.farewell是一个常量变量:
public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static final String farewell = "Bye bye"; public void sayGoodbye() { System.out.println(farewell); } } EnglishGoodbye myEnglishGoodbye = new EnglishGoodbye(); myEnglishGoodbye.sayGoodbye(); }
- javaSE_8系列博客——Java语言的特性(三)--类和对象(17)--嵌套类(本地/局部类)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(15)--嵌套类
- javaSE_8系列博客——Java语言的特性(三)--类和对象(16)--嵌套类(内部类的示例)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(18)--嵌套类(匿名类)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(19)--嵌套类(Lambda 表达式)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(20)--嵌套类(Lambda 表达式--VS--方法引用)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(9)--对象的创建
- javaSE_8系列博客——Java语言的特性(三)--类和对象(10)--对象的使用
- javaSE_8系列博客——Java语言的特性(三)--类和对象(8)--对象
- javaSE_8系列博客——Java语言的特性(三)--类和对象(3)--类的声明
- javaSE_8系列博客——Java语言的特性(三)--类和对象(13)--理解类的成员
- javaSE_8系列博客——Java语言的特性(三)--类和对象(2)--类(宏观概述)
- javaSE_8系列博客——Java语言的特性(三)--类和对象(1)--概述
- javaSE_8系列博客——Java语言的特性(三)--类和对象(4)--声明成员变量
- javaSE_8系列博客——Java语言的特性(三)--类和对象(5)--定义方法
- javaSE_8系列博客——Java语言的特性(三)--类和对象(11)--从方法返回值
- javaSE_8系列博客——Java语言的特性(三)--类和对象(12)--使用this关键字
- javaSE_8系列博客——Java语言的特性(三)--类和对象(14)--初始化字段
- ARM内核版本及SOC版本
- 产品开发阶段 EVT DVT PVT MP
- zsore和经验法则(统计学原理)
- Sonar简介
- TVS管与ESD保护二极管的区别
- javaSE_8系列博客——Java语言的特性(三)--类和对象(17)--嵌套类(本地/局部类)
- STM32 CubeMX如何生成微秒(us)级延时
- STM32 CubeMX 中如何查看系统时钟
- 相机调效果 说的IQ tuning 是什么意思
- define 中强制类型转换及浮点数后面带f
- STM32 的几种输入输出模式
- Mysql5.7
- ScrollView嵌套ListView显示不全时原理浅析
- 【mysql】插入时中文变为??