Java作用域、遮蔽与限定访问详解
立即解锁
发布时间: 2025-08-18 02:21:28 阅读量: 2 订阅数: 12 

### Java 作用域、遮蔽与限定访问详解
#### 1. 内部类对封闭作用域的使用
内部类的代码可以使用封闭作用域中的简单名称,包括封闭类的类成员和实例成员,以及封闭块的局部变量。这一特性为 Java 编程带来了很大的灵活性,使得内部类能够方便地访问外部环境中的数据。
#### 2. 编译单元作用域
编译单元作用域是一个重要的概念,它仅适用于通过单类型导入或按需类型导入声明导入的公共类和接口类型的名称。这些类型名称在包含导入声明的编译单元内有效,但不适用于同一包中的其他编译单元。
提出这个概念是为了强调导入声明仅对其所在的编译单元有效。新手程序员有时会错误地认为在一个编译单元中输入的导入声明对同一包中的所有其他编译单元都有效。实际上,这样做不仅会不必要地减慢包中许多类和接口的编译过程,还可能引入命名冲突。
#### 3. 嵌套类型成员对封闭作用域声明的遮蔽
嵌套类型(无论是声明的还是继承的)的成员会遮蔽封闭作用域中同名的实体。以下是相关示例:
```java
class Test {
public static void main(String[] args) {
System.out.println(new Test().new NestedType().s);
}
class ScopeTest { } //declaration is an enclosing scope
class NestedType {
class ScopeTest { } //declared member
String s = new ScopeTest().getClass().getName();
}
}
```
执行上述程序会输出 `Test$NestedType$ScopeTest`,这是 `NestedType` 中声明的内部成员类的二进制名称。
再看另一个示例:
```java
class Test {
public static void main(String[] args) {
new EnclosingClass.NestedType().print();
}
String scopeTest() { return "inheritance"; }
}
class EnclosingClass {
static String scopeTest() { return "enclosing scope"; }
static class NestedType extends Test {
void print() {
System.out.println(scopeTest());
}
}
}
```
执行此程序会输出 `inheritance`。这个例子有趣的地方在于,`NestedType` 继承的实例方法遮蔽了 `Test` 中的静态方法。在包含层次结构中,实例方法可以遮蔽静态方法,但在继承层次结构中,这样做会导致编译器报错,因为实例方法不能覆盖静态方法。
遮蔽声明的规范并不完善,最初的内部类规范就存在这个问题。第二版的《Java 语言规范》(JLS)中对其描述如下:类类型 `C` 中声明或继承的成员 `m` 的作用域是 `C` 的整个主体,包括任何嵌套类型声明。如果 `C` 本身是嵌套类,封闭作用域中可能存在与 `m` 相同类型(变量、方法或类型)的定义。在所有这些情况下,`C` 中声明或继承的成员 `m` 会遮蔽 `m` 的其他定义。不过,该规范仅提及了类类型,同样的规范也应包含在关于接口的章节中。
#### 4. 未命名包中类型的作用域
未命名包中的类和接口只有在编译单元顶部没有包声明时才在作用域内。例如,以下 `Directory` 类没有包声明,属于未命名包:
```java
public class Directory {
private static String name = "C:\\Java\\classes";
public String getName() { return name; }
}
```
下面的程序无法编译,因为未命名包的成员不在作用域内:
```java
package com.javarules.examples;
class Test {
public static void main(String[] args) {
String name = new Directory().getName();
```
0
0
复制全文
相关推荐










