局部类
来源:互联网 发布:mac app store无法下载 编辑:程序博客网 时间:2024/05/19 23:13
局部类
局部类是定义在一个代码块里的类。 那么什么是一个代码块呢? 在一组花括号里包含一个或者多个语句的代码片段就可以叫做代码块。局部类通常定义在一个方法的内部。
声明局部类
局部类可以定义在任何代码块里,它可以出现在在方法内、一个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"); }}
验证电话号码的逻辑是首先把里面的非数字字符去掉,然后看看号码的长度是不是刚好10位 (北美的电话号码长度),这个例子会输出以下结果:
First number is 1234567890Second number is invalid
一个局部类是可以访问包装它的类的成员的, 在上面的例子中,PhoneNumber的构造方法就访问了包装类的成员:
LocalClassExample.regularExpression
而且局部类也可以访问局部变量,然而局部类只能访问final的局部变量。当局部类访问局部变量或者封闭块的参数时,它会留存(可以复制一个副本来使用的,因为我知道你不会变动)那个变量或者参数。例如,PhoneNumber的构造方法可以访问局部变量
numberLength,就是因为它是final的, numberLength是一个可以留存的变量。
然而从Java 8开始,局部类除了可以访问final的局部变量和参数,还可以访问事实上是final的变量(尽管没有加final修饰符)。 如果一个变量或者参数从它初始化之后就从来没有修改过,那么事实它就是一个final的变量或者参数。例如,假定
numberLength没有加final修饰符,你又在
PhoneNumber的构造方法里对它做了点小手脚,改动了它。
PhoneNumber(String phoneNumber) { <strong>numberLength = 7;</strong> String currentNumber = phoneNumber.replaceAll( regularExpression, ""); if (currentNumber.length() == numberLength) formattedPhoneNumber = currentNumber; else formattedPhoneNumber = null;}
好吧,就是因为你动了手脚,改变了它的值,变量
numberLength就不在被看作是纯洁的也就是final的了。因此,编译就会报错:内部类引用的局部变量必须是final的或者事实上是final的。
从Java 8开始,如果局部类是定义在一个方法内部的,它是可以访问方法的参数的。例如你可以在局部类
PhoneNumber内定义方法
public void printOriginalNumbers() { System.out.println("Original numbers are " + phoneNumber1 +" and " + phoneNumber2);}方法
printOriginalNumbers就访问了方法validatePhoneNumber的参数phoneNumber1和phoneNumber2
遮蔽和局部类
如果在局部类里声明的类型(例如变量)和它的包装类的类型名字一样,那么局部类的变量就会遮蔽包装类的变量作用范围, 如果只用名字访问,只会对当前局部类生效。
局部类和内部类相似
局部类和内部类一样,不能定义声明静态的成员。如果局部类出现在了静态方法里 (例如刚才的例子PhoneNumber是定义在静态方法validatePhoneNumber中的)只能引用它的包装类的静态成员。 假如你没有把成员变量regularExpression
定义成静态的,编译就会报错:非静态变量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(); }
public void sayGoodbyeInEnglish() { class EnglishGoodbye { public static void sayGoodbye() { System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); }
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(); }
- 局部类
- 局部类
- 局部类怎么访问局部变量
- 嵌套类 局部类
- 嵌套类、局部类
- 嵌套类 局部类
- 嵌套类、局部类
- 小议局部类
- C++局部类
- C#中的局部类
- C++的局部类
- C++局部类
- C++局部类
- C++ 局部类
- c++ _局部类
- 匿名与局部类
- 局部变量,类变量
- 局部类和嵌套类
- Git分支
- Java面向对象作业-用接口方式测试向下转型
- centos中redis3 cluster集群的搭建
- Java报表工具
- LeetCode 144. Binary Tree Preorder Traversal
- 局部类
- 怎么控制popupwindow现实的位置
- 浅谈MySQL数据库优化
- ionic中的页面传值问题
- HTML学习
- error: ‘for’ loop initial declarations are only allowed in C99 mode
- 编程,如何编程,什么是编程
- Java面向对象--Object类
- STM32时钟配置及相关问题