Previous Table of Contents Next


14.2.6.2. The char Type

char values represent characters. Character literals may appear in a Java program between single quotes. For example:

   char c = ‘A’;

All of the standard C character escapes, as well as Unicode escapes, are also supported in character literals. For example:

   char newline = ‘\n’, apostrophe = ‘\’’,
       delete = ‘\377’, aleph=’\u05D0’;

Values of type char do not have a sign. If a char is cast to a byte or a short, a negative value may result.

The char type in Java holds a two-byte Unicode character. While this may seem intimidating to those not familiar with Unicode and the techniques of program internationalization, it is in fact totally transparent. Java does not provide a way to compute the size of a variable, nor does it allow any sort of pointer arithmetic. What this means is that if you are only using ASCII or Latin-1 characters, there is no way to distinguish a Java char from a C char.

14.2.6.3. Integral Types

The integral types in Java are byte, short, char, int, and long. Literals for these types are written just as they are in C. All integral types, other than char, are signed. There is no unsigned keyword as there is in C. It is not legal to write long int or short int as it is in C. A long constant may be distinguished from other integral constants by appending the character l or L to it.

Integer division by zero or modulo zero causes an ArithmeticException to be thrown.6


6Exceptions signal errors in Java. Exception handling is described later.

14.2.6.4. Floating-Point Types

The floating-point types in Java are float and double. Literals for these types are written just as they are in C. Literals may be specified to be of type float by appending an f or F to the value; they may be specified to be of type double by appending a d or D.

float and double types have special values that may be the result of certain floating-point operations: positive infinity, negative infinity, negative zero, and not-a-number. The java.lang.Float and java.lang.Double classes define some of these values as constants: POSITIVE_INFINITY, NEGATIVE_INFINITY, and NaN.

NaN is unordered—comparing it to any other number, including itself, yields false. Use Float.isNaN() or Double.isNaN() to test for NaN. Negative zero compares equal to regular zero (positive zero), but the two zeros may be distinguished by division: One divided by negative zero yields negative infinity; one divided by positive zero yields positive infinity.

Floating-point arithmetic never causes exceptions, even in the case of division by zero.

14.2.6.5. String Literals

Strings in Java are not a primitive type but are instances of the String class. However, because they are so commonly used, string literals may appear between quotes in Java programs, just as they do in C. When the compiler encounters such a string literal, it automatically creates the necessary String object.

14.2.7. Reference Data Types

The non-primitive data types in Java are objects and arrays. These non-primitive types are often called “reference types” because they are handled “by reference”—in other words, the address of the object or array is stored in a variable, passed to methods, and so on. By comparison, primitive types are handled “by value”—the actual primitive values are stored in variables and passed to methods.

In C, you can manipulate a value by reference by taking its address with the & operator, and you can “dereference” an address with the * and -> operators. These operators do not exist in Java: Primitive types are always passed by value; arrays and objects are always passed by reference.

Because objects are passed by reference, two different variables may refer to the same object:

   Button p, q;
   p = new Button();            // p refers to a Button object
   q = p;                       // q refers to the same Button.
   p.setLabel(“Ok”);            // A change to the object through p...
   String s = q.getLabel();     // ...is also visible through q.
                                // s now contains “Ok”.

This is not true of primitive types, however:

   int i = 3;                   // i contains the value 3.
   int j = i;                   // j contains a copy of the value in i.
   i = 2;                       // Changing i doesn’t change j.
                                // Now, i =\^= 2 and j =\^= 3.
   .\” djf: this is a new B-head

14.2.7.1. Terminology: Pass by Reference

The statement that Java manipulates objects “by reference” causes confusion for some programmers, because there are several different meanings of “by reference” in common use. Regardless of what we call it, it is important to understand what Java does. Java works with references to objects. A Java variable holds only a reference to an object, not the object itself. When an object is passed to a method, only a reference to the object is actually passed, not the entire object. It is in this sense that Java manipulates objects “by reference.”

Some people use the term “pass by reference” to mean that a reference to a variable is passed to a method. Java does not do this. For example, it is not possible to write a working swap() function like the following in Java:

   public void swap(Object a, Object b) {
     Object temp = a;
     a = b;
     b = temp;
   }

The method parameters a and b contain references to objects, not addresses of variables. Thus, while this swap() function does compile and run, it has no effect except on its own local variables and arguments.

To solve this terminology problem, perhaps we should say that Java manipulates objects “by reference,” but it passes object references to methods “by value.”


Previous Table of Contents Next