java 局部类_Java™ 教程(局部类)

局部类

局部类是在块中定义的类,它是一对大括号之间的一组零个或多个语句,你通常会在方法体中找到定义的局部类。

声明局部类

你可以在任何块中定义局部类(有关详细信息,请参阅表达式、语句和块),例如,你可以在方法体、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 1234567890

Second number is invalid

访问封闭类的成员

局部类可以访问其封闭类的成员,在前面的示例中,PhoneNumber构造函数访问成员LocalClassExample.regularExpression。

此外,局部类可以访问局部变量,但是,局部类只能访问声明为final的局部变量,当局部类访问封闭块的局部变量或参数时,它会捕获该变量或参数。例如,PhoneNumber构造函数可以访问局部变量numberLength,因为它被声明为final;numberLength是捕获的变量。

但是,从Java SE 8开始,局部类可以访问final或有效final的封闭块的局部变量和参数,在初始化之后其值永远不会改变的变量或参数实际上是final,例如,假设变量numberLength未声明为final,并且你在PhoneNumber构造函数中添加赋值语句,以将有效电话号码的长度更改为7位数:

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是在方法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被声明为static,当遇到此方法定义时,编译器会生成类似于“修饰符'static'的错误,只允许在常量变量声明中使用”:

public void sayGoodbyeInEnglish() {

class EnglishGoodbye {

public static void sayGoodbye() {

System.out.println("Bye bye");

}

}

EnglishGoodbye.sayGoodbye();

}

局部类可以具有静态成员,前提是它们是常量变量(常量变量是原始类型或类型String的变量,它被声明为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();

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值