1.概述
编译Java类时,将创建一个具有相同名称的类文件。但是,对于嵌套类或嵌套接口,它会创建一个类文件,该文件的名称将内部类和外部类名(包括美元符号)组合在一起。
在本文中,我们将看到所有这些情况。
2.细节
在Java中,我们可以在一个类中编写一个类。其中编写的类称为嵌套类,而保存嵌套类的类称为外部类。嵌套类的范围受其封闭类的范围限制。
同样,我们可以在另一个接口或类中声明一个接口。这样的接口称为嵌套接口。
我们可以使用嵌套的类和接口对仅在一个地方使用的实体进行逻辑分组。这不仅使我们的代码更具可读性和可维护性,而且还增加了封装性。
在下一节中,我们将详细讨论其中的每一个。我们还将看一下枚举。
3.嵌套类
嵌套类是在另一个类或接口内声明的类。每当我们需要一个单独的类,但仍希望该类充当另一个类的一部分时,嵌套类是实现它的最佳方法。
当我们编译Java文件时,它将.class
文件,为所有嵌套的类创建单独的类文件。为封闭类生成的类文件将具有与Java类相同的名称。
对于嵌套类,**编译器使用其他命名约定–** **OuterClassName$NestedClassName.class**
首先,让我们创建一个简单的Java类:
public class Outer {
// variables and methods...
}
当我们编译 Outer
类,编译器将创建一个 Outer.class
文件。
在接下来的小节中,我们将在 Outer
类,并查看类文件的命名方式。
3.1 静态嵌套类
顾名思义,被声明为static
的嵌套类称为静态嵌套类。在Java中,仅允许嵌套类为static.
静态嵌套类可以同时具有静态和非静态字段和方法。它们与外部类相关联,而不与特定实例相关联。因此,我们不需要外部类的实例来访问它们。
Outer
类中声明一个静态嵌套类:
public class Outer {
static class StaticNested {
public String message() {
return "This is a static Nested Class";
}
}
}
当我们编译Outer
类时,
编译器会创建两个类文件,一个用于Outer
,另一个用于StaticNested
:
3.2 非静态嵌套类
非静态嵌套类(也称为内部类)与封闭类的实例相关联,并且它们可以访问外部类的所有变量和方法。
外部类只能具有公共或默认访问权限,而内部类可以是私有,公共,受保护或具有默认访问权限。但是,它们不能包含任何静态成员。另外,我们需要创建外部类的实例来访问内部类。
让我们在Outer
类中再添加一个嵌套类:
public class Outer {
class Nested {
public String message() {
return "This is a non-static Nested Class";
}
}
}
它会再生成一个类文件:
3.3 局部类
局部类(也称为内部类)在一个块中定义-平衡括号之间的一组语句。例如,它们可以在方法主体, for
循环或if
子句中。局部类的范围与局部变量一样,被限制在块内。本地类在编译时显示为带有自动生成的数字的美元符号。
为本地类生成的类文件使用命名约定– **OuterClassName$1LocalClassName.class**
让我们在方法中声明一个本地类:
public String message() {
class Local {
private String message() {
return "This is a Local Class within a method";
}
}
Local local = new Local();
return local.message();
}
Local
类创建一个单独的类文件:
同样,我们可以在if
子句中声明一个本地类:
public String message(String name) {
if (StringUtils.isEmpty(name)) {
class Local {
private String message() {
return "This is a Local class within if clause";
}
}
Local local = new Local();
return local.message();
} else
return "Welcome to " + name;
}
尽管我们正在创建另一个具有相同名称的本地类,但编译器不会报错。它会再创建一个类文件,并以增加的数量命名:
3.4 匿名内部类
顾名思义,匿名类是没有名称的内部类。编译器在美元符号后使用自动生成的数字来命名类文件。
我们需要同时在单个表达式中声明和实例化匿名类。它们通常扩展现有的类或实现接口。
让我们看一个简单的例子:
public String greet() {
Outer anonymous = new Outer() {
@Override
public String greet() {
return "Running Anonymous Class...";
}
};
return anonymous.greet();
}
在这里,我们通过扩展Outer
类创建了一个匿名类,编译器又添加了一个类文件:
同样,我们可以使用匿名类实现接口。
在这里,我们正在创建一个接口:
interface HelloWorld {
public String greet(String name);
}
现在,让我们创建一个匿名类:
public String greet(String name) {
HelloWorld helloWorld = new HelloWorld() {
@Override
public String greet(String name) {
return "Welcome to "+name;
}
};
return helloWorld.greet(name);
}
让我们观察一下修订后的类文件列表:
如我们所见,为接口HelloWorld
生成了一个类文件,为名称为Outer$2
的匿名类生成了一个类文件。
3.5 接口内部类
我们已经在另一个类中看到了一个类,此外,我们可以在接口中声明一个类。如果类的功能与接口功能紧密相关,则可以在接口内部声明它。当我们要为接口方法编写默认实现时,可以使用此内部类。
HelloWorld
接口中声明一个内部类:
interface HelloWorld {
public String greet(String name);
class InnerClass implements HelloWorld {
@Override
public String message(String name) {
return "Inner class within an interface";
}
}
}
编译器又生成了一个类文件:
4.嵌套接口
嵌套接口(也称为内部接口)在类或另一个接口中声明。使用嵌套接口的主要目的是通过对相关接口进行分组来解析名称空间。
我们不能直接访问嵌套接口。只能使用外部类或外部接口访问它们。例如, Map
接口内部Entry
接口是嵌套的,可以作为Map
访问。 Entry
。
让我们看看如何创建嵌套接口。
4.1 接口内部接口
接口内部声明的接口是隐式公共的。
让我们在HelloWorld
接口中声明我们的接口:
interface HelloWorld {
public String greet(String name);
interface HelloSomeone{
public String greet(String name);
}
}
这将为嵌套接口HelloWorld$HelloSomeone
的新类文件。
4.2 类内部的接口
在类内部声明的接口可以使用任何访问修饰符。
让我们在Outer
类中声明一个接口:
public class Outer {
interface HelloOuter {
public String hello(String name);
}
}
它将生成一个名为以下文件的新类文件: OuterClass$StaticNestedClass
5.枚举
枚举是在Java 5中引入的。它是一种数据类型,包含一组固定的常量,而这些常量是该enum
的实例。
在enum
声明定义了一个称为电子NUM类型(也称为枚举数据类型)类。 enum
添加很多东西,例如构造函数,方法,变量以及称为常量特定的类主体的东西。
创建enum
,我们正在创建一个新类,并且隐式扩展了Enum
类。 Enum
不能继承任何其他类,也不能扩展。但是,它可以实现一个接口。
我们可以在其自己的源文件或另一个类成员中将enum
让我们看看创建enum
所有方法。
5.1 枚举类
首先,让我们创建一个简单的enum
:
enum Level {
LOW, MEDIUM, HIGH;
}
编译后,编译器将为我们的枚举Level
5.2 类中的枚举
现在,让我们在Outer
类中enum
public class Outer {
enum Color{
RED, GREEN, BLUE;
}
}
编译器将为我们的嵌套枚举Outer$Color
的单独的类文件。
5.3 接口内的枚举
同样,我们可以在接口内enum
interface HelloWorld {
enum DIRECTIONS {
NORTH, SOUTH, EAST, WEST;
}
}
HelloWorld
接口时,编译器将再添加一个名为HelloWorld$Directon.
5.4 枚举内的枚举
我们可以声明一个enum
另一个内部enum
:
enum Foods {
DRINKS, EATS;
enum DRINKS {
APPLE_JUICE, COLA;
}
enum EATS {
POTATO, RICE;
}
}
最后,让我们看一下生成的类文件:
enum
类型创建一个单独的类文件。
六,结论
在本文中,我们看到了用于Java类文件的不同命名约定。我们在单个Java文件中添加了类,接口和枚举,并观察了编译器如何为它们中的每个创建单独的类文件。
0 评论