Thinking in Java - 4th Edition
1079 pág.

Thinking in Java - 4th Edition

Disciplina:Programação Orientada a Objetos1.261 materiais32.115 seguidores
Pré-visualização50 páginas
for primitive members

When a primitive data type is a member of a class, it is guaranteed to get a default value if
you do not initialize it:

Primitive type Default

boolean false

char ‘\u0000’ (null)

Everything Is an Object 47 

48 Thinking in Java Bruce Eckel

Primitive type Default

byte (byte)0

short (short)0

int 0

long 0L

float 0.0f

double 0.0d

The default values are only what Java guarantees when the variable is used as a member of a
class. This ensures that member variables of primitive types will always be initialized
(something C++ doesn’t do), reducing a source of bugs. However, this initial value may not
be correct or even legal for the program you are writing. It’s best to always explicitly initialize
your variables.

This guarantee doesn’t apply to local variables—those that are not fields of a class. Thus, if
within a method definition you have:

int x;

Then x will get some arbitrary value (as in C and C++); it will not automatically be initialized
to zero. You are responsible for assigning an appropriate value before you use x. If you forget,
Java definitely improves on C++: You get a compile-time error telling you the variable might
not have been initialized. (Many C++ compilers will warn you about uninitialized variables,
but in Java these are errors.)

Methods, arguments,
 and return values

In many languages (like C and C++), the term function is used to describe a named
subroutine. The term that is more commonly used in Java is method, as in “a way to do
something.” If you want, you can continue thinking in terms of functions. It’s really only a
syntactic difference, but this book follows the common Java usage of the term “method.”

Methods in Java determine the messages an object can receive. The fundamental parts of a
method are the name, the arguments, the return type, and the body. Here is the basic form:

ReturnType methodName( /* Argument list */ ) {
 /* Method body */
}

The return type describes the value that comes back from the method after you call it. The
argument list gives the types and names for the information that you want to pass into the
method. The method name and argument list (which is called the signature of the method)
uniquely identify that method.

Methods in Java can be created only as part of a class. A method can be called only for an
object,3 and that object must be able to perform that method call. If you try to call the wrong
method for an object, you’ll get an error message at compile time. You call a method for an
object by naming the object followed by a period (dot), followed by the name of the method
and its argument list, like this:

                                                            
3 static methods, which you’ll learn about soon, can be called for the class, without an object.

objectName.methodName(arg1, arg2, arg3);

For example, suppose you have a method f( ) that takes no arguments and returns a value of
type int. Then, if you have an object called a for which f( ) can be called, you can say this:

int x = a.f();

The type of the return value must be compatible with the type of x. This act of calling a
method is commonly referred to as sending a message to an object. In the preceding
example, the message is f( ) and the object is a. Object-oriented programming is often
summarized as simply “sending messages to objects.”

The argument list

The method argument list specifies what information you pass into the method. As you might
guess, this information—like everything else in Java—takes the form of objects. So, what you
must specify in the argument list are the types of the objects to pass in and the name to use
for each one. As in any situation in Java where you seem to be handing objects around, you
are actually passing references.4 The type of the reference must be correct, however. If the
argument is supposed to be a String, you must pass in a String or the compiler will give an
error. Consider a method that takes a String as its argument. Here is the definition, which
must be placed within a class definition for it to be compiled:

int storage(String s) {
 return s.length() * 2;
}

This method tells you how many bytes are required to hold the information in a particular
String. (The size of each char in a String is 16 bits, or two bytes, to support Unicode
characters.) The argument is of type String and is called s. Once s is passed into the method,
you can treat it just like any other object. (You can send messages to it.) Here, the length( )
method is called, which is one of the methods for Strings; it returns the number of
characters in a string.

You can also see the use of the return keyword, which does two things. First, it means
“Leave the method, I’m done.” Second, if the method produces a value, that value is placed
right after the return statement. In this case, the return value is produced by evaluating the
expression s.length( ) * 2.

You can return any type you want, but if you don’t want to return anything at all, you do so by
indicating that the method returns void. Here are some examples:

boolean flag() { return true; }
double naturalLogBase() { return 2.718; }
void nothing() { return; }
void nothing2() {}

When the return type is void, then the return keyword is used only to exit the method, and
is therefore unnecessary when you reach the end of the method. You can return from a
method at any point, but if you’ve given a non-void return type, then the compiler will force
you (with error messages) to return the appropriate type of value regardless of where you
return.

At this point, it can look like a program is just a bunch of objects with methods that take
other objects as arguments and send messages to those other objects. That is indeed much of

Everything Is an Object 49 

what goes on, but in the following chapter you’ll learn how to do the detailed low-level work
by making decisions within a method. For this chapter, sending messages will suffice.

Building a Java program
There are several other issues you must understand before seeing your first Java program.

Name visibility

A problem in any programming language is the control of names. If you use a name in one
module of the program, and another programmer uses the same name in another module,
how do you distinguish one name from another and prevent the two names from “clashing”?
In C this is a particular problem because a program is often an unmanageable sea of names.
C++ classes (on which Java classes are based) nest functions within classes so they cannot
clash with function names nested within other classes. However, C++ still allows global data
and global functions, so clashing is still possible. To solve this problem, C++ introduced
namespaces using additional keywords.

Java was able to avoid all of this by taking a fresh approach. To produce an unambiguous
name for a library, the Java creators want you to use your Internet domain name in reverse
since domain names are guaranteed to be unique. Since my domain name is
MindView.net, my utility library of foibles would be named
net.mindview.utility.foibles. After your reversed domain name, the dots are intended to
represent subdirectories.

In Java 1.0 and Java 1.1 the domain extensions com, edu, org, net, etc., were capitalized by
convention, so the library would appear: NET.mindview.utility.foibles. Partway through
the development of Java 2, however, it was discovered that this caused problems, so now the
entire package name is lowercase.

This mechanism means that all of your files automatically live in their own namespaces, and
each class within a file must have a unique identifier—the language prevents name clashes for
you.

Using other components

Whenever you want to use a predefined class in your program, the compiler must know how
to locate it. Of course, the class might already exist in the same source-code