java_language_specification_java_se_17_edition_chapter_4_-_types_values_and_variables

Java Language Specification Java SE 17 Edition Chapter 4 - Types, Values, and Variables

Return to Java 17 Language Spec Table of Contents, Java 17 Language Spec, Java Language Specifications, Language Specifications, Java bibliography, Java DevOps, Java, Java topics, Awesome Java, Java development tools

“ (JSR-392 JvLngSpc17 2021)

4

C H A P T E R

Types, Values, and Variables

THE Java programming language is a statically typed language, which means that every variable and every expression has a type that is known at compile time.

The Java programming language is also a strongly typed language, because types limit the values that a variable (§4.12) can hold or that an expression can produce, limit the operations supported on those values, and determine the meaning of the operations. Strong static [[typing helps detect errors at compile time.

The types of the Java programming language are divided into two kinds: primitive types and reference types. The primitive types (§4.2) are the boolean type and the numeric types. The numeric types are the integral types byte, short, int, long, and char, and the floating-point types float and double. The reference types (§4.3)

are class types, interface types, and array types. There is also a special null type. An object (§4.3.1) is a dynamically created instance of a class type or a dynamically created array. The values of a reference type are references to objects. All objects, including arrays, support the methods of class Object (§4.3.2). String literals are represented by String objects (§4.3.3).

4.1 The Kinds of Types and Values

There are two kinds of types in the Java programming language: primitive types

(§4.2) and reference types (§4.3). There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values (§4.2) and reference values (§4.3).

Type:

PrimitiveType

ReferenceType

53

4.2

Primitive Types and Values

TYPES, VALUES]], AND VARIABLES

There is also a special null type, the type of the expression null (§3.10.8, §15.8.1), which has no name.

Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type.

The null reference is the only possible value of an expression of null type.

The null reference can always be assigned or cast to any reference type (§5.2, §5.3,

§5.5).

In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.

4.2 Primitive Types and Values

A primitive type is predefined by the Java programming language and named by

its reserved keyword (§3.9):

PrimitiveType:

{Annotation} NumericType

{Annotation} boolean

NumericType:

IntegralType

FloatingPointType

IntegralType:

(one of)

byte short int long char

FloatingPointType:

(one of)

float double

Primitive values do not share state with other primitive values.

The numeric types are the integral types and the floating-point types.

The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose

values are 16-bit unsigned integers representing UTF-16 code units (§3.1).

54

TYPES, VALUES]], AND VARIABLES

Primitive Types and Values

4.2

The floating-point types are float, whose values exactly correspond to the 32-bit IEEE 754 binary32 floating-point numbers, and double, whose values exactly

correspond to the 64-bit IEEE 754 binary64 floating-point numbers.

The boolean type has exactly two values: true and false.

4.2.1

Integral Types and Values

The values of the integral types are integers in the following ranges:

  • For long, from -9223372036854775808 to 9223372036854775807, inclusive
  • For char, from '\u0000' to '\uffff' inclusive, that is, from 0 to 65535

4.2.2

Integer Operations

The Java programming language provides a number of operators that act on integral values:

– The numerical]] comparison operators <, ⇐, >, and >= (§15.20.1)

– The numerical]] equality operators == and != (§15.21.1)

– The unary plus and minus operators + and - (§15.15.3, §15.15.4)

– The multiplicative operators *, /, and % (§15.17)

– The additive operators + and - (§15.18)

– The increment operator ++, both prefix (§15.15.1) and postfix (§15.14.2)

– The decrement operator –, both prefix (§15.15.2) and postfix (§15.14.3)

– The signed and unsigned shift operators «, », and »> (§15.19)

– The bitwise complement operator ~ (§15.15.5)

– The integer bitwise [[operators &, ^, and | (§15.22.1)

55

4.2

Primitive Types and Values

TYPES, VALUES]], AND VARIABLES

(the decimal form of a byte, short, int, or long operand, or the character of a char operand), and then produce a newly created String that is the concatenation of the two strings

Other useful constructors, methods, and constants are predefined in the classes Byte, Short, Integer, Long, and Character.

If an integer operator other than a shift operator has at least one operand of type long, then the operation is carried out using 64-bit precision, and the result of the numerical operator is of type long. If the other operand is not long, it is first widened (§5.1.5) to type long by numeric promotion (§5.6).

Otherwise, the operation is carried out using 32-bit precision, and the result of the numerical operator is of type int. If either operand is not an int, it is first widened to type int by numeric promotion.

The integer operators do not indicate overflow or underflow in any way.

Any value of any integral type may be cast to or from any numeric type. There are no casts between integral types and the type boolean.

See §4.2.5 for an idiom to convert integer expressions to boolean.

An integer operator can throw an exception (§11 ( Exceptions)) for the following reasons:

conversion (§5.1.8) of a null reference is required.

(§15.17.3) can throw an ArithmeticException if the right-hand operand is zero.

(§15.14.3, §15.15.2) can throw an OutOfMemoryError if boxing conversion

(§5.1.7) is required and there is not sufficient memory available to perform the conversion.

Example 4.2.2-1. Integer Operations

class Test {

public static void main(String[] args) {

int i = 1000000;

System.out]].println(i * i);

56

TYPES, VALUES]], AND VARIABLES

Primitive Types and Values

4.2

long l = i;

System.out]].println(l * l);

System.out]].println(20296 / (l - i));

}

}

This program produces the output:

-727379968

1000000000000

and then encounters an ArithmeticException in the division by l - i, because l

- i is zero. The first multiplication is performed in 32-bit precision, whereas the second multiplication is a long multiplication. The value -727379968 is the decimal value of the low 32 bits of the mathematical result, 1000000000000, which is a value too large for type int.

4.2.3

Floating-Point Types and Values

The floating-point types are float and double, which are conceptually associated with the 32-bit binary32 and 64-bit binary64 floating-point formats for IEEE 754

values and operations, as specified in the IEEE 754 Standard (§1.7).

In Java SE 15 and later, the Java programming language uses the 2019 version of the IEEE

754 Standard. Prior to Java SE 15, the Java programming language used the 1985 version of the IEEE 754 Standard, where the binary32 format was known as the single format and the binary64 format was known as the double format.

IEEE 754 includes not only positive and negative number]]s that consist of a sign and magnitude, but also positive and negative zeros, positive and negative infinities, and special Not-a-Number values (hereafter abbreviated NaN). A NaN value is used to represent the result of certain invalid operations such as dividing zero by zero. NaN constants of both float and double type are predefined as Float.NaN

and Double.NaN.

The finite nonzero values of a floating-point type can all be expressed in the form s ⋅ m ⋅ 2( e - N + 1), where:

  • s is +1 or -1,

Some values can be represented in this form in more than one way. For example,

supposing that a value v of a floating-point type might be represented in this form 57

4.2

Primitive Types and Values

TYPES, VALUES]], AND VARIABLES

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 subnormal. If a value of a floating-point type cannot be represented in such a way that m ≥ 2 N-1, then the value is said to be a subnormal value, because its magnitude is below the magnitude of the smallest normalized value.

The constraints on the parameters N and K (and on the derived parameters Emin and Emax) for float and double are summarized in Table 4.2.3-A.

Table 4.2.3-A. Floating-point parameters

Parameter

float

double

N

24

53

K

8

11

Emax

+127

+1023

Emin

-126

-1022

Except for NaN, floating-point values are ordered. Arranged from smallest to largest, they are negative infinity, negative finite nonzero values, positive and negative zero, positive finite nonzero values, and positive infinity.

IEEE 754 allows multiple distinct NaN values for each of its binary32 and binary64

floating-point formats. However, the Java SE Platform generally treats NaN values of a given floating-point type as though collapsed into a single canonical value, and hence this specification normally refers to an arbitrary NaN as though to a canonical value.

Under IEEE 754, a floating-point operation with non-NaN arguments may generate a NaN result. IEEE 754 specifies a set of NaN bit patterns, but does not mandate which particular NaN bit pattern is used to represent a NaN result; this is left to the hardware architecture. A programmer can create NaNs with different bit patterns to encode, for example, retrospective diagnostic information. These NaN values can be created with the Float.intBitsToFloat and Double.longBitsToDouble methods for

float and double, respectively. Conversely, to inspect the bit patterns of NaN values, the Float.floatToRawIntBits and Double.doubleToRawLongBits methods can be

used for float and double, respectively.

Positive zero and negative zero compare equal, so the result of the expression 0.0==-0.0 is true and the result of 0.0>-0.0 is false. Other operations can distinguish positive and negative zero; for example, 1.0/0.0 has the value positive infinity, while the value of 1.0/-0.0 is negative infinity.

58

TYPES, VALUES]], AND VARIABLES

Primitive Types and Values

4.2

NaN is unordered, so:

both operands are NaN (§15.20.1).

In particular, (x<y) == !(x>=y) will be false if x or y is NaN.

In particular, x!=x is true if and only if x is NaN.

4.2.4

Floating-Point Operations

The Java programming language provides a number of operators that act on floating-point values:

– The numerical]] comparison operators <, ⇐, >, and >= (§15.20.1)

– The numerical]] equality operators == and != (§15.21.1)

– The unary plus and minus operators + and - (§15.15.3, §15.15.4)

– The multiplicative operators *, /, and % (§15.17)

– The additive operators + and - (§15.18.2)

– The increment operator ++, both prefix (§15.15.1) and postfix (§15.14.2)

– The decrement operator –, both prefix (§15.15.2) and postfix (§15.14.3)

then produce a newly created String by concatenating the two strings

Other useful constructors, methods, and constants are predefined in the classes Float, Double, and Math.

If at least one of the operands to a binary operator is of floating-point type, then the operation is a floating-point operation, even if the other operand is integral.

59

4.2

Primitive Types and Values

TYPES, VALUES]], AND VARIABLES

If at least one of the operands to a numerical operator is of type double, then the operation is carried out using 64-bit floating-point arithmetic, and the result of the numerical operator is a value of type double. If the other operand is not a double, it is first widened (§5.1.5) to type double by numeric promotion (§5.6).

Otherwise, at least one of the operands is of type float; the operation is carried out using 32-bit floating-point arithmetic, and the result of the numerical operator is a value of type float. If the other operand is not a float, it is first widened to type float by numeric promotion.

Floating-point arithmetic is carried out in accordance with the rules of the IEEE

754 Standard, including for overflow and underflow (§15.4), with the exception of the remainder operator % (§15.17.3).

Any value of a floating-point type may be cast to or from any numeric type. There are no casts between floating-point types and the type boolean.

See §4.2.5 for an idiom to convert floating-point expressions to boolean.

A floating-point operator can throw an exception (§11 ( Exceptions)) for the following reasons:

conversion (§5.1.8) of a null reference is required.

(§15.14.3, §15.15.2) can throw an OutOfMemoryError if boxing conversion

(§5.1.7) is required and there is not sufficient memory available to perform the conversion.

Example 4.2.4-1. Floating-point Operations

class Test {

public static void main(String[] args) {

// An example of overflow:

double d = 1e308;

System.out]].print(”overflow produces infinity: “);

System.out]].println(d + “

  • 10==” + d*10);

// An example of gradual underflow:

d = 1e-305 * Math.PI;

System.out]].print(“gradual underflow: ” + d + “\n ”);

for (int i = 0; i < 4; i++)

System.out]].print(” “ + (d /= 100000));

System.out]].println();

// An example of NaN:

System.out]].print(“0.0/0.0 is Not-a-Number: ”);

d = 0.0/0.0;

System.out]].println(d);

// An example of inexact results and rounding]]:

60

TYPES, VALUES]], AND VARIABLES

Primitive Types and Values

4.2

System.out]].print(”inexact results with float:“);

for (int i = 0; i < 100; i++) {

float z = 1.0f / i;

if (z

  • i != 1.0f)

System.out]].print(” “ + i);

}

System.out]].println();

// Another example of inexact results and rounding]]:

System.out]].print(”inexact results with double:“);

for (int i = 0; i < 100; i++) {

double z = 1.0 / i;

if (z

  • i != 1.0)

System.out]].print(” “ + i);

}

System.out]].println();

// An example of cast to integer rounding]]:

System.out]].print(”cast to int rounds toward 0: “);

d = 12345.6;

System.out]].println1);

}

}

This program produces the output:

overflow produces infinity: 1.0E308*10==Infinity

gradual underflow: 3.141592653589793E-305

3.1415926535898E-310 3.141592653E-315 3.142E-320 0.0

0.0/0.0 is Not-a-Number: NaN

inexact results with float: 0 41 47 55 61 82 83 94 97

inexact results with double: 0 49 98

cast to int rounds toward 0: 12345 -12345

This example demonstrates, among other things, that gradual underflow can result in a gradual loss of precision.

The results when i is 0 involve division by zero, so that z becomes positive infinity, and z

4.2.5

The boolean Type and boolean Values

The boolean type represents a logical quantity with two possible values, indicated by the literals true and false (§3.10.3).

The boolean operators are:

61

4.3

Reference Types and Values

TYPES, VALUES]], AND VARIABLES

(either ”true“ or ”false“), and then produce a newly created String that is the concatenation of the two strings

Boolean expressions determine the control flow in several kinds of statements:

  • The while statement]] (§14.12)

A boolean expression also determines which subexpression is evaluated in the conditional ? : operator (§15.25).

Only boolean and Boolean expressions can be used in control flow statements and

as the first operand of the conditional operator ? :.

An integer or floating-point expression x can be converted to a boolean value, following the C language convention that any nonzero value is true, by the expression x!=0.

An object reference obj can be converted to a boolean value, following the C

language convention that any reference other than null is true, by the expression obj!=null.

A boolean value can be converted to a String by string conversion (§5.4).

A boolean value may be cast to type boolean, Boolean, or Object (§5.5). No other casts on type boolean are allowed.

4.3 Reference Types and Values

There are four kinds of reference types: class types (§8.1), interface types (§9.1), type variables (§4.4), and array types (§10.1).

62

TYPES, VALUES]], AND VARIABLES

Reference Types and Values

4.3

ReferenceType:

ClassOrInterfaceType

TypeVariable

ArrayType

ClassOrInterfaceType:

ClassType

InterfaceType

ClassType:

{Annotation} TypeIdentifier TypeArguments ]

PackageName . {Annotation} TypeIdentifier [ TypeArguments]

ClassOrInterfaceType . {Annotation} TypeIdentifier TypeArguments ]

InterfaceType:

ClassType

TypeVariable:

{Annotation} TypeIdentifier

ArrayType:

PrimitiveType Dims

ClassOrInterfaceType Dims

TypeVariable Dims

Dims:

{Annotation} [ ]

1)
int)d + ” “ + (int)(-d
java_language_specification_java_se_17_edition_chapter_4_-_types_values_and_variables.txt · Last modified: 2022/05/20 09:51 by 127.0.0.1