Every object belongs to some particular class: the class that was mentioned in the
creation expression that produced the object, the class whose class object was
used to invoke the newInstance
method (§20.3.6) to produce the object, or the
String
class for objects implicitly created by the string concatenation operator +
(§15.17.1). This class is called the class of the object. (Arrays also have a class, as
described at the end of this section.) An object is said to be an instance of its class
and of all superclasses of its class.
(Sometimes a variable or expression is said to have a "run-time type" but that is an abuse of terminology; it refers to the class of the object referred to by the value of the variable or expression at run time, assuming that the value is not null
. Properly speaking, type is a compile-time notion. A variable or expression has a type; an object or array has no type, but belongs to a class.)
The type of a variable is always declared, and the type of an expression can be deduced at compile time. The type limits the possible values that the variable can hold or the expression can produce at run time. If a run-time value is a reference that is not null
, it refers to an object or array that has a class (not a type), and that class will necessarily be compatible with the compile-time type.
Even though a variable or expression may have a compile-time type that is an interface type, there are no instances of interfaces. A variable or expression whose type is an interface type can reference any object whose class implements (§8.1.4) that interface.
Here is an example of creating new objects and of the distinction between the type of a variable and the class of an object:
public interface Colorable { void setColor(byte r, byte g, byte b); }
class Point { int x, y; } class ColoredPoint extends Point implements Colorable {
byte r, g, b;
public void setColor(byte rv, byte gv, byte bv) { r = rv; g = gv; b = bv; }
}
class Test { public static void main(String[] args) { Point p = new Point(); ColoredPoint cp = new ColoredPoint(); p = cp; Colorable c = cp; } }
p
of the method main
of class Test
has type Point
and is initially assigned a reference to a new instance of class Point
.
cp
similarly has as its type ColoredPoint
, and is initially assigned a reference to a new instance of class ColoredPoint
.
cp
to the variable p
causes p
to hold a reference to a ColoredPoint
object. This is permitted because ColoredPoint
is a subclass of Point
, so the class ColoredPoint
is assignment compatible (§5.2) with the type Point
. A ColoredPoint
object includes support for all the methods of a Point
. In addition to its particular fields r
, g
, and b
, it has the fields of class Point
, namely x
and y
.
c
has as its type the interface type Colorable
, so it can hold a reference to any object whose class implements Colorable
; specifically, it can hold a reference to a ColoredPoint
.
new Colorable()
" is not valid because it is not possible to create an instance of an interface, only of a class.
Every array also has a class; the method getClass
(§20.1.1), when invoked for an array object, will return a class object (of class Class
) that represents the class of the array. The classes for arrays have strange names that are not valid Java identifiers; for example, the class for an array of int
components has the name "[I
" and so the value of the expression:
new int[10].getClass().getName()
is the string "[I"
; see §20.1.1 for details.
Oft on the dappled turf at ease
I sit, and play with similes,
Loose types of things through all degrees.
William Wordsworth, To the Same Flower