Sunday, November 9, 2008

Declaring Objects

Declaring Objects

 

As just explained, when you create a class, you are creating a new data type. You can use this type to declare objects of that type. However, obtaining objects of a class is a two-step process. First, you must declare a variable of the class type. This variable does not define an object. Instead, it is simply a variable that can refer to an object. Second, you must acquire an actual, physical copy of the object and assign it to that variable. You can do this using the new operator. The new operator dynamically allocates (that is, allocates at run time) memory for an object and returns a reference to it. This reference is, more or less, the address in memory of the object allocated by new.  

 

This reference is then stored in the variable. Thus, in Java, all class objects must be dynamically allocated. Let's look at the details of this procedure.

In the preceding sample programs, a line similar to the following is used to declare an object of type Box:

 

Box mybox = new Box();

 

This statement combines the two steps just described. It can be rewritten like this to show each step more clearly:

 

Box mybox; // declare reference to object

mybox = new Box(); // allocate a Box object

 

The first line declares mybox as a reference to an object of type Box. After this line executes, mybox contains the value null, which indicates that it does not yet point to an actual object. Any attempt to use mybox at this point will result in a compile-time error. The next line allocates an actual object and assigns a reference to it to mybox. After the second line executes, you can use mybox as if it were a Box object. But in reality, mybox simply holds the memory address of the actual Box object. The effect of these two lines of code is depicted in Figure 6-1.

 

JAVA

Those readers familiar with C/C++ have probably noticed that object references appear to be similar to pointers. This suspicion is, essentially, correct. An object reference is similar to a memory pointer. The main difference—and the key to Java's safety—is that you cannot manipulate references as you can actual pointers. Thus, you cannot cause an object reference to point to an arbitrary memory location or manipulate it like an integer.

 

A Closer Look at new

As just explained, the new operator dynamically allocates memory for an object.

 

It has this general form:

 

class-var = new classname( );

 

Here, class-var is a variable of the class type being created.  The classname is the name of the class that is being instantiated.

 

The class name followed by parentheses specifies the constructor for the class. A constructor defines what occurs when an object of a class is created. Constructors are an important part of all classes and have many significant attributes.

 

Most real-world classes explicitly define their own constructors within their class definition. However, if no explicit constructor is specified, then Java will automatically supply a default constructor. This is the case with Box.

 

For now, we will use the default constructor. Soon, you will see how to define your own constructors. At this point, you might be wondering why you do not need to use new for such things as integers or characters. The answer is that Java's simple types are not implemented as objects. Rather, they are implemented as "normal" variables. This is done in the interest of efficiency.

 

As you will see, objects have many features and attributes that require Java to treat them differently than it treats the simple types. By not applying the same overhead to the simple types that applies to objects,

 

Java can implement the simple types more efficiently. Later, you will see object versions of the simple types that are available for your use in those situations in which complete objects of these types are needed. It is important to understand that new allocates memory for an object during run time.

 

The advantage of this approach is that your program can create as many or as few objects as it needs during the execution of your program. However, since memory is finite, it is possible that new will not be able to allocate memory for an object because insufficient memory exists.

 

If this happens, a run-time exception will occur. (You will learn how to handle this and other exceptions in next posts.) For the sample programs in this book, you won't need to worry about running out of memory, but you will need to consider this possibility in real-world programs that you write.

 

Let's once again review the distinction between a class and an object. A class creates a new data type that can be used to create objects. That is, a class creates a logical framework that defines the relationship between its members. When you declare an object of a class, you are creating an instance of that class. Thus, a class is a logical construct. An object has physical reality. (That is, an object occupies space in memory.)  It is important to keep this distinction clearly in mind.

 

Assigning Object Reference Variables

 

Object reference variables act differently than you might expect when an assignment takes place. For example, what do you think the following fragment does?

 

Box b1 = new Box();

Box b2 = b1;

 

You might think that b2 is being assigned a reference to a copy of the object referred to by b1. That is, you might think that b1 and b2 refer to separate and distinct objects.

 

However, this would be wrong. Instead, after this fragment executes, b1 and b2 will both refer to the same object. The assignment of b1 to b2 did not allocate any memory or copy any part of the original object. It simply makes b2 refer to the same object as does b1.

 

Thus, any changes made to the object through b2 will affect the object to which b1 is referring, since they are the same object.

 

This situation is depicted here: Although b1 and b2 both refer to the same object, they are not linked in any other way.

 

For example, a subsequent assignment to b1 will simply unhook b1 from the original object without affecting the object or affecting b2.

 

For example:

Box b1 = new Box();

Box b2 = b1;

// ...

b1 = null;

 

Here, b1 has been set to null, but b2 still points to the original object.

 

When you assign one object reference variable to another object reference variable, you are not creating a copy of the object, you are only making a copy of the reference.

No comments: