Java源代码解析-续篇-语法(类)

Java源代码解析系列目录

Java源代码解析-开篇-词法
Java源代码解析-续篇-语法(类型、值和变量)
Java源代码解析-续篇-语法(名称)
Java源代码解析-续篇-语法(包和模块)
Java源代码解析-续篇-语法(类)
Java源代码解析-续篇-语法(枚举,记录)
Java源代码解析-续篇-语法(接口)
Java源代码解析-续篇-语法(数组)
Java源代码解析-续篇-语法(块,语句和模式)
Java源代码解析-续篇-语法(表达式)
Java源代码解析-续篇-ANTLR语法规则文件中的左递归处理

Java源代码解析-续篇-语法(类)


引言

在之前的篇章中,我们已经深入探讨了Java的词法基础、类型与变量、名称,以及包与模块的语法,这些构成了Java程序的基本骨架,接下来是Java中最为核心也最为复杂的部分 的语法机器结构,该语法结构在官方规范的第8章定义

规范中使用 { x } 的语法表示x可以出现零次或多次

规范中使用 [ x ] 的语法表示x可以出现零次或一次

Classes(类)

规范中对类有以下定义:

  • 类声明定义了一个新的类,并描述了它的实现方式
  • 一个顶级类是在编译单元中直接声明的类
  • 嵌套类是指在另一个类或接口声明的主体内部声明的任何类,嵌套类可以是成员类、局部类或匿名类
  • 某些类型的嵌套类是内部类,内部类可以引用封闭类的实例、局部变量和类型变量
  • 枚举类是用简化语法声明的类,它定义了一组少量的命名类实例
  • 记录类是用简化语法声明的类,它定义了一个简单的值聚合

Class Declaration(类声明)

Class Declaration(类声明) 由 Normal Class Declaration(普通类声明),Enum Declaration(枚举声明),Record Declaration(记录声明)组成

NormalClassDeclaration
EnumDeclaration
RecordDeclaration

Normal Class Declaration(普通类声明)

Normal Class Declaration(普通类声明) 由 Type Identifier(类型标识符),Type Parameters(类型参数),Class Modifier(类修饰符),Class Implements(类实现),Class Permits(类许可),Class Extends(类继承),class(类声明关键字),Class Body(类体)组成

{ClassModifier} class TypeIdentifier [TypeParameters] [ClassExtends] [ClassImplements] [ClassPermits] ClassBody

普通类声明根据规范描述来看非常简单:零到多个“类修饰符”“类声明关键字”“类型标识符”零到一个“类型参数”零到一个“类继承”零到一个“类实现”零到一个“类许可”“类体”

原文部分截图如下:
类声明
例:

// 类声明
classDeclaration:
    normalClassDeclaration
    | enumDeclaration
    | recordDeclaration
    ;

// 普通类声明
normalClassDeclaration:
    classModifier* CLASS typeIdentifier typeParameters? classExtends? classImplements? classPermits? classBody
    ;

Class Modifier(类修饰符) 由 private(访问控制关键字),non-sealed(非密封类关键字),static(静态关键字),public(访问控制关键字),protected(访问控制关键字),sealed(密封类关键字),final(不可派生关键字),abstract(抽象关键字),strictfp(IEEE 754标准浮点运算关键字),Annotation(注解)组成

Annotation public protected private abstract static final sealed non-sealed strictfp

类修饰符就是注解和一些关键字,语法上可以出现多个,语义上有不同的限制

原文部分截图如下:
类修饰符
例:

// 类修饰符
classModifier:
    annotation
    | PUBLIC
    | PROTECTED
    | PRIVATE
    | ABSTRACT
    | STATIC
    | FINAL
    | SEALED
    | NON_SEALED
    | STRICTFP
    ;

Type Parameters(类型参数) 由 Type Parameter List(类型参数列表),<(操作符),>(操作符)组成

< TypeParameterList >

Type Parameter List(类型参数列表) 由 Type Parameter(类型参数),,(分隔符)组成

TypeParameter {, TypeParameter}

这里的类型参数可以结合之前 Java源代码解析-续篇-语法(类型、值和变量)里的类型变量语法内容来看,其实就是泛型类的形参

原文部分截图如下:
类型参数2
例:

// 类型参数
typeParameters:
    LT typeParameterList GT
    ;

// 类型参数列表
typeParameterList:
    typeParameter (COMMA typeParameter)*
    ;

Class Extends(类继承) 由 extends(继承关键字),Class Type(类类型)组成

extends ClassType

Java在语法上就定义了单继承,这里不做赘述,顺便骂一句多继承,一个娃咋能有俩爹呢?!

Class Implements(类实现) 由 implements(类实现声明关键字),Interface Type List(接口类型列表)组成

implements InterfaceTypeList

Interface Type List(接口类型列表) 由 Interface Type(接口类型),,(分隔符)组成

InterfaceType {, InterfaceType}

类实现语法不做赘述

Class Permits(类许可) 由 Type Name(类型名称),permits(允许子类关键字),,(分隔符)组成

permits TypeName {, TypeName}

对于 Class Permits(类许可)在语义上要结合 Class Modifier(类修饰符)中的密封类关键字结合来看
以下非语法内容

密封类是在Java15中引入的,作用就是限制继承增加安全性,并且增加代码可读性(这里并不是很认同,允许子类超多的话一样很费劲),相对于粗暴的 final(不可派生关键字),使用密封可以更加灵活的控制类的继承,例如指定只有类A,B,C可以继承类D,其他类不可以继承

原文部分截图如下:
类继承
类实现
类密封

例:

// 类继承
classExtends:
    EXTENDS classType
    ;

// 类实现
classImplements:
    IMPLEMENTS interfaceTypeList
    ;

// 接口类型列表
interfaceTypeList:
    interfaceType (COMMA interfaceType)*
    ;

// 类许可
classPermits:
    PERMITS typeName (COMMA typeName)*
    ;

Class Body(类体)

Class Body(类体) 由 {(分隔符),Class Body Declaration(类体声明),}(分隔符)组成

{ {ClassBodyDeclaration} }

Class Body Declaration(类体声明) 由 Static Initializer(静态初始化器),Constructor Declaration(构造器声明),Instance Initializer(实例初始化器),Class Member Declaration(类成员声明)组成

ClassMemberDeclaration
InstanceInitializer
StaticInitializer
ConstructorDeclaration

Class Member Declaration(类成员声明) 由 Class Declaration(类声明),Method Declaration(方法声明),Interface Declaration(接口声明),;(分隔符),Field Declaration(字段声明)组成

FieldDeclaration
MethodDeclaration
ClassDeclaration
InterfaceDeclaration
;

官方规范将类体内部分为四类,最主要的是 Class Member Declaration(类成员声明)其中包含所有的成员变量和方法,然后是三个比较特殊的 Static Initializer(静态初始化器),Constructor Declaration(构造器声明),Instance Initializer(实例初始化器),在此简单说明

  • Instance Initializer(实例初始化器)就是类中的独立代码快用 { } 包裹,这个代码快没有名字,没有标识符,就是个光秃秃的代码块儿,类实例化时在构造函数之前执行
  • Static Initializer(静态初始化器)就是用 static(静态关键字)修饰 Instance Initializer(实例初始化器),它在类加载的时候执行
  • Constructor Declaration(构造器声明)就是类的构造函数定义语法

Class Member Declaration(类成员声明)也被分为四大类,分别是成员方法,成员接口声明,成员变量

  • 还有可以出现在不同成员之间的,而且出现次数不限的 分号

原文部分截图如下:
类体
例:

// 类体
classBody:
    LBRACE classBodyDeclaration* RBRACE
    ;

// 类体声明
classBodyDeclaration:
    classMemberDeclaration
    | instanceInitializer
    | staticInitializer
    | constructorDeclaration
    ;

// 类成员声明
classMemberDeclaration:
    fieldDeclaration
    | methodDeclaration
    | classDeclaration
    | interfaceDeclaration
    | SEMI
    ;

Field Declaration(字段声明)

Field Declaration(字段声明) 由 Unann Type(无注解类型),Variable Declarator List(变量声明符列表),;(分隔符),Field Modifier(字段修饰符)组成

{FieldModifier} UnannType VariableDeclaratorList ;

Field Modifier(字段修饰符) 由 private(访问控制关键字),static(静态关键字),public(访问控制关键字),protected(访问控制关键字),transient(忽略序列化关键字),final(不可变关键字),volatile(多线程可见性修饰符关键字),Annotation(注解)组成

Annotation public protected private
static final transient volatile

Variable Declarator List(变量声明符列表) 由 ,(分隔符),Variable Declarator(变量声明符)组成

VariableDeclarator {, VariableDeclarator}

Variable Declarator(变量声明符) 由 Variable Declarator Id(变量声明符ID),=(操作符),Variable Initializer(变量初始化器)组成

VariableDeclaratorId [= VariableInitializer]

Variable Declarator Id(变量声明符ID) 由 Identifier(标识符),Dims(维度)组成

Identifier [Dims]

Variable Initializer(变量初始化器) 由 Expression(表达式),Array Initializer(数组初始化器)组成

Expression
ArrayInitializer

Unann Type(无注解类型) 由 Unann Primitive Type(无注解基本类型),Unann Reference Type(无注解引用类型)组成

UnannPrimitiveType
UnannReferenceType

Unann Primitive Type(无注解基本类型) 由 Numeric Type(数值类型),boolean(布尔类型关键字)组成

NumericType
boolean

Unann Reference Type(无注解引用类型) 由 Unann Class Or Interface Type(无注解类或接口类型),Unann Array Type(无注解数组类型),Unann Type Variable(无注解类型变量)组成

UnannClassOrInterfaceType
UnannTypeVariable
UnannArrayType

Unann Class Or Interface Type(无注解类或接口类型) 由 Unann Interface Type(无注解接口类型),Unann Class Type(无注解类类型)组成

UnannClassType
UnannInterfaceType

Unann Class Type(无注解类类型) 由 Type Identifier(类型标识符),Unann Class Or Interface Type(无注解类或接口类型),Package Name(包名),Type Arguments(类型参数),.(分隔符),Annotation(注解)组成

TypeIdentifier [TypeArguments]
PackageName . {Annotation} TypeIdentifier [TypeArguments]
UnannClassOrInterfaceType . {Annotation} TypeIdentifier [TypeArguments]

Unann Interface Type(无注解接口类型) 由 Unann Class Type(无注解类类型)组成

UnannClassType

Unann Type Variable(无注解类型变量) 由 Type Identifier(类型标识符)组成

TypeIdentifier

Unann Array Type(无注解数组类型) 由 Unann Class Or Interface Type(无注解类或接口类型),Unann Primitive Type(无注解基本类型),Dims(维度),Unann Type Variable(无注解类型变量)组成

UnannPrimitiveType Dims
UnannClassOrInterfaceType Dims
UnannTypeVariable Dims

对于 Field Declaration(字段声明)的语法中的 Unann xxx 语法叫做 无注解xxx,其实就是为了和普通的类型做区分,这种类型是不可以使用注解去修饰的

举个例子

// 以下方法中String这个类型就是无注解类型 Unann Type
// 而Integer是可以有注解的类型
public String method(@SomeAnn Integer i) {}

原文部分截图如下:
字段声明1
字段声明2
字段声明3

例:

// 字段声明
fieldDeclaration:
    fieldModifier* unannType variableDeclaratorList SEMI
    ;

// 字段修饰符
fieldModifier:
    annotation
    | PUBLIC
    | PROTECTED
    | PRIVATE
    | STATIC
    | FINAL
    | TRANSIENT
    | VOLATILE
    ;

// 变量声明列表
variableDeclaratorList:
    variableDeclarator (COMMA variableDeclarator)*
    ;

// 变量声明
variableDeclarator:
    variableDeclaratorId (ASSIGN variableInitializer)?
    ;

// 变量声明ID
variableDeclaratorId:
    identifier dims?
    ;

// 变量初始化器
variableInitializer:
    expression
    | arrayInitializer
    ;

// 无注解类型
unannType:
    unannPrimitiveType
    | unannReferenceType
    ;

// 无注解原始类型
unannPrimitiveType:
    numericType
    | BOOLEAN
    ;

// 无注解引用类型
unannReferenceType:
    unannClassOrInterfaceType
    | unannTypeVariable
    | unannArrayType
    ;

// 无注解类或接口类型
unannClassOrInterfaceType:
    unannClassType
    | unannInterfaceType
    ;

// 无注解类类型
unannClassType:
    typeIdentifier typeArguments?
    | (packageName | unannClassOrInterfaceType) DOT annotation* typeIdentifier typeArguments?
    ;

// 无注解接口类型
unannInterfaceType:
    unannClassType
    ;

// 无注解类型变量
unannTypeVariable:
    typeIdentifier
    ;

// 无注解数组类型
unannArrayType:
    (unannPrimitiveType | unannClassOrInterfaceType | unannTypeVariable) dims
    ;

Method Declaration(方法声明)

Method Declaration(方法声明) 由 Method Body(方法体),Method Modifier(方法修饰符),Method Header(方法头)组成

{MethodModifier} MethodHeader MethodBody

Method Modifier(方法修饰符) 由 synchronized(代码块同步执行关键字),private(访问控制关键字),static(静态关键字),public(访问控制关键字),protected(访问控制关键字),native(本地方法关键字),final(不可重写关键字),abstract(抽象关键字),strictfp(IEEE 754标准浮点运算关键字),Annotation(注解)组成

Annotation public protected private abstract static final synchronized native strictfp

Method Header(方法头) 由 Type Parameters(类型参数),Method Declarator(方法声明符),Throws(抛出),Annotation(注解),Result(方法返回结果)组成

Result MethodDeclarator [Throws]
TypeParameters {Annotation} Result MethodDeclarator [Throws]

Result(方法返回结果) 由 Unann Type(无注解类型),void(空值关键字)组成

UnannType
void

Method Declarator(方法声明符) 由 Formal Parameter List(形式参数列表),Identifier(标识符),Receiver Parameter(接收者参数),((分隔符),)(分隔符),Dims(维度),,(分隔符)组成

Identifier ( [ReceiverParameter ,] [FormalParameterList] ) [Dims]

Receiver Parameter(接收者参数) 由 Unann Type(无注解类型),Identifier(标识符),this(引用当前对象关键字),Annotation(注解),.(分隔符)组成

{Annotation} UnannType [Identifier .] this

Formal Parameter List(形式参数列表) 由 Formal Parameter(形式参数),,(分隔符)组成

FormalParameter {, FormalParameter}

Formal Parameter(形式参数) 由 Unann Type(无注解类型),Variable Declarator Id(变量声明符ID),Variable Arity Parameter(可变参数),Variable Modifier(变量修饰符)组成

{VariableModifier} UnannType VariableDeclaratorId
VariableArityParameter

Variable Arity Parameter(可变参数) 由 Unann Type(无注解类型),Identifier(标识符),Variable Modifier(变量修饰符),Annotation(注解),(可变长形参定义符号)组成

{VariableModifier} UnannType {Annotation} … Identifier

Variable Modifier(变量修饰符) 由 final(不可变关键字),Annotation(注解)组成

Annotation
final

Throws(抛出) 由 throws(抛出异常声明关键字),Exception Type List(异常类型列表)组成

throws ExceptionTypeList

Exception Type List(异常类型列表) 由 Exception Type(异常类型),,(分隔符)组成

ExceptionType {, ExceptionType}

Exception Type(异常类型) 由 Type Variable(类型变量),Class Type(类类型)组成

ClassType
TypeVariable

Method Body(方法体) 由 Block(代码块),;(分隔符)组成

Block
;

这里只对方法的整体结构相关语法进行了描述

原文部分截图如下:
方法声明1
方法声明2
方法声明3
方法声明4
方法声明5
方法声明6
例:

// 方法声明
methodDeclaration:
    methodModifier* methodHeader methodBody
    ;

// 方法修饰符
methodModifier:
    annotation
    | PUBLIC
    | PROTECTED
    | PRIVATE
    | ABSTRACT
    | STATIC
    | FINAL
    | SYNCHRONIZED
    | NATIVE
    | STRICTFP
    ;

// 方法头
methodHeader:
    (typeParameters annotation*)? result methodDeclarator throwsSyntax?
    ;

// 返回结果
result:
    unannType
    | VOID
    ;

// 方法声明符
methodDeclarator:
    identifier LPAREN (receiverParameter COMMA)? formalParameterList? RPAREN dims?
    ;

// 接收者参数
receiverParameter:
    annotation* unannType (identifier DOT)? THIS
    ;

// 形式参数列表
formalParameterList:
    formalParameter (COMMA formalParameter)*
    ;

// 形式参数
formalParameter:
    variableModifier* unannType variableDeclaratorId
    | variableArityParameter
    ;

// 可变参数
variableArityParameter:
    variableModifier* unannType annotation* ELLIPSIS identifier
    ;

// 变量修饰符
variableModifier:
    annotation
    | FINAL
    ;

// 抛出
throwsSyntax:
    THROWS exceptionTypeList
    ;

// 异常类型列表
exceptionTypeList:
    exceptionType (COMMA exceptionType)*
    ;

// 异常类型
exceptionType:
    classType
    | typeVariable
    ;

// 方法体
methodBody:
    block
    | SEMI
    ;

Initializer(初始化器)

Instance Initializer(实例初始化器) 由 Block(代码块)组成

Block

Static Initializer(静态初始化器) 由 static(静态关键字),Block(代码块)组成

static Block

初始化器很简单就很只有静态和非静态之分,就是个代码块儿,不做赘述

原文部分截图如下:
初始化器1
初始化器2
例:

// 实例初始化器
instanceInitializer:
    block
    ;

// 静态初始化器
staticInitializer:
    STATIC block
    ;

Constructor Declaration(构造器声明)

Constructor Declaration(构造器声明) 由 Constructor Declarator(构造器声明符),Constructor Body(构造器体),Throws(抛出),Constructor Modifier(构造器修饰符)组成

{ConstructorModifier} ConstructorDeclarator [Throws] ConstructorBody

Constructor Modifier(构造器修饰符) 由 private(访问控制关键字),public(访问控制关键字),protected(访问控制关键字),Annotation(注解)组成

Annotation public protected private

Constructor Declarator(构造器声明符) 由 Formal Parameter List(形式参数列表),Type Parameters(类型参数),Receiver Parameter(接收者参数),((分隔符),)(分隔符),,(分隔符),Simple Type Name(简单类型名称)组成

[TypeParameters] SimpleTypeName
( [ReceiverParameter ,] [FormalParameterList] )

Simple Type Name(简单类型名称) 由 Type Identifier(类型标识符)组成

TypeIdentifier

Constructor Body(构造器体) 由 Explicit Constructor Invocation(显式构造器调用),Block Statements(块语句),{(分隔符),}(分隔符)组成

{ [ExplicitConstructorInvocation] [BlockStatements] }

Explicit Constructor Invocation(显式构造器调用) 由 super(引用父类关键字),Type Arguments(类型参数),Primary(基本表达式),this(引用当前对象关键字),((分隔符),)(分隔符),;(分隔符),Argument List(参数列表),.(分隔符),Expression Name(表达式名称)组成

[TypeArguments] this ( [ArgumentList] ) ;
[TypeArguments] super ( [ArgumentList] ) ;
ExpressionName . [TypeArguments] super ( [ArgumentList] ) ;
Primary . [TypeArguments] super ( [ArgumentList] ) ;

原文部分截图如下:
构造器1
构造器2
构造器3
构造器4
例:

// 构造器声明
constructorDeclaration:
    constructorModifier* constructorDeclarator throwsSyntax? constructorBody
    ;

// 构造器修饰符
constructorModifier:
    annotation
    | PUBLIC
    | PROTECTED
    | PRIVATE
    ;

// 构造器声明符
constructorDeclarator:
    typeParameters? simpleTypeName LPAREN (receiverParameter COMMA)? formalParameterList? RPAREN
    ;

// 简单类型名
simpleTypeName:
    typeIdentifier
    ;

// 构造器体
constructorBody:
    LBRACE explicitConstructorInvocation? blockStatements? RBRACE
    ;

// 显式构造调用
explicitConstructorInvocation:
    typeArguments? (THIS | SUPER) LPAREN argumentList? RPAREN SEMI
    | (expressionName | primary) DOT typeArguments? SUPER LPAREN argumentList? RPAREN SEMI
    ;

0 error(s) 0 warning(s)

暂告一段落

好了,至此描述了规范中第8章 Classes(类)中的语法,较为详细的描述了Java中类的语法结构,并给出了ANTLR4的g4文件部分实例。对于 Enum Declaration(枚举声明)和 Record Declaration(记录声明)的部分将在下一篇内容描述。对本文有任何疑问或想要进一步探讨,私信,评论或邮箱:ElyarZakir@outlook.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值