System, but they may not be reproduced for publication



Yüklə 83 Mb.
Pdf görüntüsü
səhifə13/82
tarix19.04.2023
ölçüsü83 Mb.
#106251
1   ...   9   10   11   12   13   14   15   16   ...   82
Java A Beginner’s Guide, Eighth Edition ( PDFDrive )

type var­name;
where type is the data type of the variable, and var­name is its name. You can declare a
variable of any valid type, including the simple types just described, and every variable
will have a type. Thus, the capabilities of a variable are determined by its type. For
example, a variable of type boolean cannot be used to store floating­point values.
Furthermore, the type of a variable cannot change during its lifetime. An int variable
cannot turn into a char variable, for example.
All variables in Java must be declared prior to their use. This is necessary because the
compiler must know what type of data a variable contains before it can properly
compile any statement that uses the variable. It also enables Java to perform strict type
checking.
Initializing a Variable
In general, you must give a variable a value prior to using it. One way to give a variable
a value is through an assignment statement, as you have already seen. Another way is
by giving it an initial value when it is declared. To do this, follow the variable’s name
with an equal sign and the value being assigned. The general form of initialization is
shown here:
type var = value;
Here, value is the value that is given to var when var is created. The value must be
compatible with the specified type. Here are some examples:
When declaring two or more variables of the same type using a comma­separated list,
you can give one or more of those variables an initial value. For example:
In this case, only b and c are initialized.
Dynamic Initialization


Dynamic Initialization
Although the preceding examples have used only constants as initializers, Java allows
variables to be initialized dynamically, using any expression valid at the time the
variable is declared. For example, here is a short program that computes the volume of
a cylinder given the radius of its base and its height:
Here, three local variables—radius, height, and volume—are declared. The first two,
radius and height, are initialized by constants. However, volume is initialized
dynamically to the volume of the cylinder. The key point here is that the initialization
expression can use any element valid at the time of the initialization, including calls to
methods, other variables, or literals.
THE SCOPE AND LIFETIME OF VARIABLES
So far, all of the variables that we have been using were declared at the start of the
main( ) method. However, Java allows variables to be declared within any block. As
explained in 
Chapter 1
, a block is begun with an opening curly brace and ended by a
closing curly brace. A block defines a scope. Thus, each time you start a new block, you
are creating a new scope. A scope determines what objects are visible to other parts of
your program. It also determines the lifetime of those objects.
In general, every declaration in Java has a scope. As a result, Java defines a powerful,
finely grained concept of scope. Two of the most common scopes in Java are those
defined by a class and those defined by a method. A discussion of class scope (and
variables declared within it) is deferred until later in this book, when classes are
described. For now, we will examine only the scopes defined by or within a method.
The scope defined by a method begins with its opening curly brace. However, if that
method has parameters, they too are included within the method’s scope. A method’s
scope ends with its closing curly brace. This block of code is called the method body.


As a general rule, variables declared inside a scope are not visible (that is, accessible) to
code that is defined outside that scope. Thus, when you declare a variable within a
scope, you are localizing that variable and protecting it from unauthorized access
and/or modification. Indeed, the scope rules provide the foundation for encapsulation.
A variable declared within a block is called a local variable.
Scopes can be nested. For example, each time you create a block of code, you are
creating a new, nested scope. When this occurs, the outer scope encloses the inner
scope. This means that objects declared in the outer scope will be visible to code within
the inner scope. However, the reverse is not true. Objects declared within the inner
scope will not be visible outside it.
To understand the effect of nested scopes, consider the following program:
As the comments indicate, the variable x is declared at the start of main( )’s scope and
is accessible to all subsequent code within main( ). Within the if block, y is declared.
Since a block defines a scope, y is visible only to other code within its block. This is why
outside of its block, the line y = 100; is commented out. If you remove the leading
comment symbol, a compile­time error will occur, because y is not visible outside of its
block. Within the if block, x can be used because code within a block (that is, a nested
scope) has access to variables declared by an enclosing scope.
Within a block, variables can be declared at any point, but are valid only after they are
declared. Thus, if you define a variable at the start of a method, it is available to all of
the code within that method. Conversely, if you declare a variable at the end of a block,


it is effectively useless, because no code will have access to it.
Here is another important point to remember: variables are created when their scope is
entered, and destroyed when their scope is left. This means that a variable will not hold
its value once it has gone out of scope. Therefore, variables declared within a method
will not hold their values between calls to that method. Also, a variable declared within
a block will lose its value when the block is left. Thus, the lifetime of a variable is
confined to its scope.
If a variable declaration includes an initializer, that variable will be reinitialized each
time the block in which it is declared is entered. For example, consider this program:
The output generated by this program is shown here:
As you can see, y is reinitialized to –1 each time the inner for loop is entered. Even
though it is subsequently assigned the value 100, this value is lost.
There is one quirk to Java’s scope rules that may surprise you: although blocks can be
nested, no variable declared within an inner scope can have the same name as a
variable declared by an enclosing scope. For example, the following program, which
tries to declare two separate variables with the same name, will not compile.


OPERATORS
Java provides a rich operator environment. An operator is a symbol that tells the
compiler to perform a specific mathematical or logical manipulation. Java has four
general classes of operators: arithmetic, bitwise, relational, and logical. Java also
defines some additional operators that handle certain special situations. This chapter
will examine the arithmetic, relational, and logical operators. We will also examine the
assignment operator. The bitwise and other special operators are examined later.
ARITHMETIC OPERATORS
Java defines the following arithmetic operators:
The operators +, –, *, and / all work the same way in Java as they do in any other
computer language (or algebra, for that matter). These can be applied to any built­in


numeric data type. They can also be used on objects of type char.
Although the actions of arithmetic operators are well known to all readers, a few special
situations warrant some explanation. First, remember that when / is applied to an
integer, any remainder will be truncated; for example, 10/3 will equal 3 in integer
division. You can obtain the remainder of this division by using the modulus operator
%. It yields the remainder of an integer division. For example, 10 % 3 is 1. In Java, the
% can be applied to both integer and floating­point types. Thus, 10.0 % 3.0 is also 1.
The following program demonstrates the modulus operator.
The output from the program is shown here:
As you can see, the % yields a remainder of 1 for both integer and floating­point
operations.
Increment and Decrement
Introduced in 
Chapter 1
, the ++ and the – – are Java’s increment and decrement
operators. As you will see, they have some special properties that make them quite
interesting. Let’s begin by reviewing precisely what the increment and decrement
operators do.
The increment operator adds 1 to its operand, and the decrement operator subtracts 1.


Therefore,
is the same as
and
is the same as
Both the increment and decrement operators can either precede (prefix) or follow
(postfix) the operand. For example,
can be written as
or as
In the foregoing example, there is no difference whether the increment is applied as a
prefix or a postfix. However, when an increment or decrement is used as part of a larger
expression, there is an important difference. When an increment or decrement operator
precedes its operand, Java will perform the corresponding operation prior to obtaining
the operand’s value for use by the rest of the expression. If the operator follows its
operand, Java will obtain the operand’s value before incrementing or decrementing it.
Consider the following:
In this case, y will be set to 11. However, if the code is written as


then y will be set to 10. In both cases, x is still set to 11; the difference is when it
happens. There are significant advantages in being able to control when the increment
or decrement operation takes place.
RELATIONAL AND LOGICAL OPERATORS
In the terms relational operator and logical operator, relational refers to the
relationships that values can have with one another, and logical refers to the ways in
which true and false values can be connected together. Since the relational operators
produce true or false results, they often work with the logical operators. For this reason
they will be discussed together here.
The relational operators are shown here:
The logical operators are shown next:
The outcome of the relational and logical operators is a boolean value.
In Java, all objects can be compared for equality or inequality using = = and !=.
However, the comparison operators, <, >, <=, or >=, can be applied only to those types
that support an ordering relationship. Therefore, all of the relational operators can be
applied to all numeric types and to type char. However, values of type boolean can


only be compared for equality or inequality, since the true and false values are not
ordered. For example, true > false has no meaning in Java.
For the logical operators, the operands must be of type boolean, and the result of a
logical operation is of type boolean. The logical operators, &, |, ^, and !, support the
basic logical operations AND, OR, XOR, and NOT, according to the following truth
table:
As the table shows, the outcome of an exclusive OR operation is true when exactly one
and only one operand is true.
Here is a program that demonstrates several of the relational and logical operators:
The output from the program is shown here:


SHORT-CIRCUIT LOGICAL OPERATORS
Java supplies special short­circuit versions of its AND and OR logical operators that
can be used to produce more efficient code. To understand why, consider the following.
In an AND operation, if the first operand is false, the outcome is false no matter what
value the second operand has. In an OR operation, if the first operand is true, the
outcome of the operation is true no matter what the value of the second operand. Thus,
in these two cases there is no need to evaluate the second operand. By not evaluating
the second operand, time is saved and more efficient code is produced.
The short­circuit AND operator is &&, and the short­circuit OR operator is ||. Their
normal counterparts are & and |. The only difference between the normal and short­
circuit versions is that the normal operands will always evaluate each operand, but
short­circuit versions will evaluate the second operand only when necessary.
Here is a program that demonstrates the short­circuit AND operator. The program
determines whether the value in d is a factor of n. It does this by performing a modulus
operation. If the remainder of n / d is zero, then d is a factor. However, since the
modulus operation involves a division, the short­circuit form of the AND is used to
prevent a divide­by­zero error.


To prevent a divide­by­zero, the if statement first checks to see if d is equal to zero. If it
is, the short­circuit AND stops at that point and does not perform the modulus division.
Thus, in the first test, d is 2 and the modulus operation is performed. The second test
fails because d is set to zero, and the modulus operation is skipped, avoiding a divide­
by­zero error. Finally, the normal AND operator is tried. This causes both operands to
be evaluated, which leads to a run­time error when the division by zero occurs.
One last point: The formal specification for Java refers to the short­circuit operators as
the conditional­or and the conditional­and operators, but the term “short­circuit” is
commonly used.
THE ASSIGNMENT OPERATOR
You have been using the assignment operator since 
Chapter 1
. Now it is time to take a
formal look at it. The assignment operator is the single equal sign, =. This operator
works in Java much as it does in any other computer language. It has this general form:

Yüklə 83 Mb.

Dostları ilə paylaş:
1   ...   9   10   11   12   13   14   15   16   ...   82




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə