- 2.1. The class File Format
- 2.2. Data Types
- 2.3. Primitive Types and Values
- 2.4. Reference Types and Values
- 2.5. Run-Time Data Areas
- 2.6. Frames
- 2.7. Representation of Objects
- 2.8. Floating-Point Arithmetic
- 2.9. Special Methods
- 2.10. Exceptions
- 2.11. Instruction Set Summary
- 2.12. Class Libraries
- 2.13. Public Design, Private Implementation
2.3. Primitive Types and Values
The primitive data types supported by the Java Virtual Machine are the numeric types, the boolean type (§2.3.4), and the returnAddress type (§2.3.3).
The numeric types consist of the integral types (§2.3.1) and the floating-point types (§2.3.2).
The integral types are:
- byte, whose values are 8-bit signed two’s-complement integers, and whose default value is zero
- short, whose values are 16-bit signed two’s-complement integers, and whose default value is zero
- int, whose values are 32-bit signed two’s-complement integers, and whose default value is zero
- long, whose values are 64-bit signed two’s-complement integers, and whose default value is zero
- char, whose values are 16-bit unsigned integers representing Unicode code points in the Basic Multilingual Plane, encoded with UTF-16, and whose default value is the null code point (’\u0000’)
The floating-point types are:
- float, whose values are elements of the float value set or, where supported, the float-extended-exponent value set, and whose default value is positive zero
- double, whose values are elements of the double value set or, where supported, the double-extended-exponent value set, and whose default value is positive zero
The values of the boolean type encode the truth values true and false, and the default value is false.
- The Java Virtual Machine Specification, First Edition did not consider boolean to be a Java Virtual Machine type. However, boolean values do have limited support in the Java Virtual Machine. The Java Virtual Machine Specification, Second Edition clarified the issue by treating boolean as a type.
The values of the returnAddress type are pointers to the opcodes of Java Virtual Machine instructions. Of the primitive types, only the returnAddress type is not directly associated with a Java programming language type.
2.3.1. Integral Types and Values
The values of the integral types of the Java Virtual Machine are:
- For byte, from -128 to 127 (-2^{7} to 2^{7} - 1), inclusive
- For short, from -32768 to 32767 (-2^{15} to 2^{15} - 1), inclusive
- For int, from -2147483648 to 2147483647 (-2^{31} to 2^{31} - 1), inclusive
- For long, from -9223372036854775808 to 9223372036854775807 (-2^{63} to 2^{63} - 1), inclusive
- For char, from 0 to 65535 inclusive
2.3.2. Floating-Point Types, Value Sets, and Values
The floating-point types are float and double, which are conceptually associated with the 32-bit single-precision and 64-bit double-precision format IEEE 754 values and operations as specified in IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std. 754-1985, New York).
The IEEE 754 standard includes not only positive and negative sign-magnitude numbers, but also positive and negative zeros, positive and negative infinities, and a special Not-a-Number value (hereafter abbreviated as “NaN”). The NaN value is used to represent the result of certain invalid operations such as dividing zero by zero.
Every implementation of the Java Virtual Machine is required to support two standard sets of floating-point values, called the float value set and the double value set. In addition, an implementation of the Java Virtual Machine may, at its option, support either or both of two extended-exponent floating-point value sets, called the float-extended-exponent value set and the double-extended-exponent value set. These extended-exponent value sets may, under certain circumstances, be used instead of the standard value sets to represent the values of type float or double.
The finite nonzero values of any floating-point value set can all be expressed in the form s · m · 2^{(e − N + 1)}, where s is +1 or −1, m is a positive integer less than 2N, and e is an integer between E_{min} = −(2^{K−1}−2) and E_{max} = 2^{K−1}−1, inclusive, and where N and K are parameters that depend on the value set. Some values can be represented in this form in more than one way; for example, supposing that a value v in a value set might be represented in this form using certain values for s, m, and e, then if it happened that m were even and e were less than 2^{K}^{-1}, one could halve m and increase e by 1 to produce a second representation for the same value v. A representation in this form is called normalized if m ≥ 2^{N-1}; otherwise the representation is said to be denormalized. If a value in a value set cannot be represented in such a way that m ≥ 2^{N-1}, then the value is said to be a denormalized value, because it has no normalized representation.
The constraints on the parameters N and K (and on the derived parameters E_{min} and E_{max}) for the two required and two optional floating-point value sets are summarized in Table 2.1.
Table 2.1. Floating-point value set parameters
Parameter |
float |
float-extended-exponent |
double |
double-extended-exponent |
N |
24 |
24 |
53 |
53 |
K |
8 |
≥ 11 |
11 |
≥ 15 |
E_{max} |
+127 |
≥ +1023 |
+1023 |
≥ +16383 |
E_{min} |
-126 |
≤ -1022 |
-1022 |
≤ -16382 |
Where one or both extended-exponent value sets are supported by an implementation, then for each supported extended-exponent value set there is a specific implementation-dependent constant K, whose value is constrained by Table 2.1; this value K in turn dictates the values for E_{min} and E_{max}.
Each of the four value sets includes not only the finite nonzero values that are ascribed to it above, but also the five values positive zero, negative zero, positive infinity, negative infinity, and NaN.
Note that the constraints in Table 2.1 are designed so that every element of the float value set is necessarily also an element of the float-extended-exponent value set, the double value set, and the double-extended-exponent value set. Likewise, each element of the double value set is necessarily also an element of the double-extended-exponent value set. Each extended-exponent value set has a larger range of exponent values than the corresponding standard value set, but does not have more precision.
The elements of the float value set are exactly the values that can be represented using the single floating-point format defined in the IEEE 754 standard, except that there is only one NaN value (IEEE 754 specifies 2^{24}-2 distinct NaN values). The elements of the double value set are exactly the values that can be represented using the double floating-point format defined in the IEEE 754 standard, except that there is only one NaN value (IEEE 754 specifies 2^{53}-2 distinct NaN values). Note, however, that the elements of the float-extended-exponent and double-extended-exponent value sets defined here do not correspond to the values that can be represented using IEEE 754 single extended and double extended formats, respectively. This specification does not mandate a specific representation for the values of the floating-point value sets except where floating-point values must be represented in the class file format (§4.4.4, §4.4.5).
The float, float-extended-exponent, double, and double-extended-exponent value sets are not types. It is always correct for an implementation of the Java Virtual Machine to use an element of the float value set to represent a value of type float; however, it may be permissible in certain contexts for an implementation to use an element of the float-extended-exponent value set instead. Similarly, it is always correct for an implementation to use an element of the double value set to represent a value of type double; however, it may be permissible in certain contexts for an implementation to use an element of the double-extended-exponent value set instead.
Except for NaNs, values of the floating-point value sets are ordered. When arranged from smallest to largest, they are negative infinity, negative finite values, positive and negative zero, positive finite values, and positive infinity.
Floating-point positive zero and floating-point negative zero compare as equal, but there are other operations that can distinguish them; for example, dividing 1.0 by 0.0 produces positive infinity, but dividing 1.0 by -0.0 produces negative infinity.
NaNs are unordered, so numerical comparisons and tests for numerical equality have the value false if either or both of their operands are NaN. In particular, a test for numerical equality of a value against itself has the value false if and only if the value is NaN. A test for numerical inequality has the value true if either operand is NaN.
2.3.3. The returnAddress Type and Values
The returnAddress type is used by the Java Virtual Machine’s jsr, ret, and jsr_w instructions (§jsr, §ret, §jsr_w). The values of the returnAddress type are pointers to the opcodes of Java Virtual Machine instructions. Unlike the numeric primitive types, the returnAddress type does not correspond to any Java programming language type and cannot be modified by the running program.
2.3.4. The boolean Type
Although the Java Virtual Machine defines a boolean type, it only provides very limited support for it. There are no Java Virtual Machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java Virtual Machine int data type.
The Java Virtual Machine does directly support boolean arrays. Its newarray instruction (§newarray) enables creation of boolean arrays. Arrays of type boolean are accessed and modified using the byte array instructions baload and bastore (§baload, §bastore).
In Oracle’s Java Virtual Machine implementation, boolean arrays in the Java programming language are encoded as Java Virtual Machine byte arrays, using 8 bits per boolean element.
The Java Virtual Machine encodes boolean array components using 1 to represent true and 0 to represent false. Where Java programming language boolean values are mapped by compilers to values of Java Virtual Machine type int, the compilers must use the same encoding.