Next: Class and Interface Behaviour, Previous: Modifiers, Up: Class and Interface Specifications
Member declarations are method, field or class initializer declarations. The declarations have the following form:
field ::= [ nsfieldmodifiers ] type ident;
clinit ::= [ methodspec ] clinitheader [ methodbody ] method ::= [ methodspec ] methodheader [ methodbody ] type ::= typename | field-built-in-type field-built-in-type ::=boolean
|byte
|char
|short
|int
|long
|float
|double
nsfieldmodifiers ::=public
|protected
|private
|final
|strictfp
|spec_public
|spec_protected
|model
|ghost
|non_null
|nullable
|peer
|rep
|readonly
Method and field declarations can be annotated with BML-modifiers. The
presence of these modifiers is signalled by setting appropriate access
flags in the BML-access flags attributes in the extended class file
(except for the model
and ghost
modifiers, as explained
above).
The BML-modifiers that can used for method declarations are
spec_public
, spec_protected
, model
, pure
,
non_null
, nullable
, helper
and the ownership
modifiers, as discussed below. In addition, each of the method's
parameters can be annotated with a modifier non_null
or
nullable
, and with any of the ownership modifiers. Local
variable declarations can be annotated with the modifiers
ghost
, non_null
and nullable
, and with the
ownership modifiers.
The BML-modifiers that can be used for field declarations are
spec_public
, spec_protected
, model
, ghost
,
non_null
, nullable
, static
and any of the
ownership modifiers.
In JML, every type can be annotated with an ownership modifier:
peer
, rep
and readonly
. For more information
about the universe type system that is encoded with these attributes,
see
Chapter 18 of the JML Reference Manual. At bytecode level, special
care has to be taken how this is modelled. First of all, if an array
is declared, it can have two ownership modifiers: one for the array
structure, and one for the elements in the array (which should not be
rep
, see [Dietl-Mueller05]). In the textual representation of
BML, an array declaration can be modified with two modifiers: the
first denotes the modifier for the array structure, the second the
modifier for the elements. In the binary BML representation (see
Encoding of BML in Class File Format), besides the flags that
represent the modifiers peer
, rep
and readonly
,
special flags elem_peer
and elem_readonly
can be set to
denote the modifier for the elements in an array. (however, the array
element ownership flag can not be set without one of the standard
ownership flags being set). Another complication is that both
specification and code can contain type specifications, (e.g.,
an expression instanceof T
, which can be decorated with
ownership modifiers. To handle the occurrence of type specifications
in expressions, the binary representation of expressions (i.e.,
type expression_info
in Encoding of Expressions)
allows ownership modifiers to occur at appropriate places. To handle
the occurrence of type specifications in instructions, the code
attributes contain a special OwnershipTable Attribute.
The semantics of the different modifiers is described in Section 6.2, Section 7.1.1, and Chapter 18 of the JML Reference Manual.
Every field declaration implicitly declares a data group. All fields (including ghost and model fields) can be specified to belong to a data group defined by another field. The class file contains a special DataGroups Attribute, containing all non-trivial data groups, i.e., data groups that do not contain only the field declaration that defined the data group, but also other fields. BML only supports static inclusion in data groups. This means that each element in the data group list contains a list of fields that are part of the data group. For more information about data groups and their semantics, see Chapter 10 of the JML Reference Manual.
At source code level, each field declaration contains a name and a type
specification. JML allows one to use a special type \TYPE
for
ghost or model variables (see
Section 7.1.2.2 of the JML Reference Manual). This type represents the
kind of all Java types. At bytecode level, the type information is
encoded as a string org.bmlspecs.TYPE
in a class descriptor
entry in the Constant Pool.
The descriptor entry for the \TYPE
type is stored in the
second constant pool (see SecondConstantPool Attribute).
The initialization of ghost fields should be specified by set instructions placed at the beginning of the appropriate initializers: static initializer <clinit> for static fields, and constructors for instance fields. Initialization of local ghost variables should be specified by set instructions inside the method, at the beginning of the variable's scope.