Wednesday, June 27, 2007

Chapter 4 - Declarations and Access Control

Chapter 4: Declarations and Access Control

Objectives

This chapter helps you to prepare for the exam by covering the following objectives:

Know how to write code that declares, constructs, and initializes arrays of any base type using
any of the permitted forms both for declaration and for initialization.
Know how to declare instance variables, static variables, and automatic (method local)
variables, making appropriate use of all permitted modifiers (such as public, final, static,
abstract, and so forth). State the significance of each of these modifiers both singly and in
combination and state the effect of package relationships on declared items qualified by these
modifiers.
Know how to identify correctly constructed method declarations and variable declarations.
Know how to determine the effect upon objects and primitive values of passing variables into
methods and performing assignments or other modifying operations in that method.


Study Strategies

As you read through this chapter, you should concentrate on the following key items:

.
How variables are declared and initialized
.
How arrays are declared and initialized
.
How methods are declared and used
.
How arguments are passed to methods
.
How methods may affect the original values and objects that are passed to them
.
How access modifiers restrict access to classes, interfaces, variables, methods, and
constructors
.
How non-access modifers are used

Chapter Introduction

Declarations are basic to writing any program in Java. You must know how to declare classes,
interfaces, variables, methods, and constructors to be a Java programmer. Although you are probably
familiar with most basic declarations, there may be a few things that you haven't encountered or you
have forgotten. This chapter will fill in any gaps in your knowledge. It covers variable and method
declarations and the use of modifiers in these declarations. Class, constructor, and interface

- 60



declarations are reviewed in Chapter 6, "Overloading, Overriding, Runtime Type, and Object
Orientation."

Declaring and Using Variables

Variable declarations are used to identify the type associated with a variable. They may also be used to
initialize a variable to a particular value of that type. Variables may be declared as a primitive type or an
object type. When a variable is declared as a primitive type, the variable's declaration identifies the type
of primitive values that may be stored by the variable. When a variable is declared as an object type, the
variable declaration identifies the type of object that may be referenced by the variable.

Java supports two different kinds of variables: field variables and local variables. Field variables are
variables that are declared as members of a class. They are also referred to as member variables or as
fields. Field variables store the information content of an object. Local variables are variables that are
declared local to a method. They are temporary placeholders for storing values and references to
objects that are used to perform a method's processing. Local variables are also referred to as
automatic variables. We'll cover field variables first, followed by local variables.

Field Variables

Field variables are declared using the following syntax:

modifiers Type declarator;
Valid modifiers are the access modifiers—public, protected, and private—and the special
modifiers—final, static, transient, and volatile. These modifiers are covered individually in
later sections of this chapter.
The variable's type may be a primitive type (boolean, byte, char, short, int, long, float, or
double), an object type (for example, String or Vector), or an array type. Array types are covered in
the next section, "Working with Arrays."
The declarator may be a simple identifier (for example, myVariable), a simple identifier followed by an
expression (for example, myVariable = 3), or an array identifier optionally followed by an expression
or array initializer.

Working with Arrays

Arrays are Java objects. However, array declarations are very flexible (and sometimes confusing), so I'll
cover them separately.

Array declarations might have the same modifiers as normal variable declarations. Array declarations
differ from other variable declarations in that they must specify the array's dimensions. Technically, Java
arrays are all one-dimensional arrays. Two-dimensional arrays are arrays of arrays. However, to
simplify this discussion, I'll still refer to an array's dimensions as if Java supported multidimensional
arrays.

The dimensions of an array may be specified to the right of its type or to the right of its identifier. Zero or
more spaces may surround the brackets that are used to identify an array's dimensions. For example,
all of the following array declarations are equivalent:

.
String[]s;
.
String []s;
.
String [] s;
.
String [ ] s;
.
String[] s;
.
String[ ] s;
.
String s[];
.
String s [];
.
String s [ ];
Multidimensional arrays (arrays of arrays) may be specified with bracket sets appearing on either or
both sides of the array name:

String[] s[];

- 61



String [][]s;

String s [] [ ];

Note that the actual size of each array dimension is not specified.

An array is created in one of two ways. The simplest way is to use an array initializer to create the array
and initialize its elements:


String[] s = {"abc","def","ghi"}
;


Multidimensional arrays may be initialized by nesting array initializers:


int[][] i = {{1,2,3}, {4,5,6}, {7,8,9}}
;
Java keeps track of the number of elements specified in each dimension and creates and initializes an
array of the correct size. However, listing array elements is only practical for very small arrays. To
create larger arrays, you must use the new operator, followed by the array's base type and one or more
sets of brackets. You specify the length of an array dimension by putting an integer within a bracket set.
For example, the following creates an array of 100 String objects:


String[] s = new String[100]
;
You can supply the lengths of multiple array dimensions using this notation. For example, the following
creates a 20 by 30 array of String objects:


String[][] s = new String[20][30]
;


The above notation is also equivalent to the following:


String[][] s = new String[20][]
;


for(int i=0; i<20; ++i)


s[i] = new String[30]
;
When an array is created, its elements are automatically initialized to default values as described in
Chapter 2, "Language Fundamentals.
"


Working with Objects

Objects are created using the new operator and the constructor of the object's class. For example, if an
object is of class C, you use a constructor of the following form:

new C(argumentList)

The argument list must correspond to the actual parameters that are declared for the constructor being
used.

When an object is created, it is typically (but not always) assigned to a variable of that type:

C myC = new C(argumentList);
The fields and methods of the object can then be referenced using the variable. For example, if C has a
field f1 and a method m1, f1 may be accessed as myC.f1 and m1 may be invoked as
myC.m1(argumentList).
In some cases, you may not want to store the newly created object before accessing it. For example,
you could use new C().m1() to invoke the m1() method of a newly created C object.
The keywords this and super are used to refer to the current object instance. When this is used
within a constructor, this refers to the object being created. When it is used within a non-static
method, this refers to the object whose method is being executed. this should not be referenced in a
static method because static methods are associated with the class as a whole rather than
specific instances of a class.
The super keyword refers to the superclass of the current object instance. It is used to reference
methods and field variables of the object's superclass that may have been hidden or overridden by
those of the object's class. The ThisSuper program (Listing 4.1) illustrates the use of this and
super.
The ThisSuper class extends SuperClass. Both ThisSuper and SuperClass define the s field
variable and display() method. The ThisSupers variable hides the SuperClass s variable and
the ThisSuperdisplay() method overrides the SuperClass display method. The ThisSuperconstructor uses this and super as follows:

- 62



display(this.s)
;
display(super.s)
;
this.display(s)
;
super.display(s)
;


These statements produce the following output:
this: this
this: super
this: this
super: this


The first three statements use the display() method of ThisSuper to display the s field variable.
The first and third statements refer to the current (ThisSuper) object instance. The second statement
uses super to refer to the svariable of SuperClass. The last statement uses super to refer to the
display() method and s variable of ThisSuper.

ThissuperListing 4.1: The Program

class ThisSuper extends SuperClass {
String s = "this";
public static void main(String[] args) {

new ThisSuper();
}
ThisSuper() {

display(this.s)
;
display(super.s)
;
this.display(s)
;
super.display(s)
;


}
void display(String s)
{
System.out.println("this: "+s)
;


}
}
class SuperClass
{


String s = "super";
void display(String s) {
System.out.println("super: "+s);
}
}

- 63



Local Variables

Local variables are declared and initialized in the same manner as field variables. However, local
variables may only specify the final modifier, which is used to identify those local variables that may
be accessed from local inner classes. Chapter 6 covers the use of local inner classes and the final
modifier.

The other major difference between local variables and field variables is their scope. A local variable
may only be accessed from within the method that it is declared. It comes into existence when the
method is executed and ceases to exist when the method's execution is completed.

Note The final Modifier The final modifier is used to indicate that the value of a

variable cannot be changed once it is assigned a value.
The non-static field variables of an object come into existence when the object is created and
continue to exist until the object is garbage collected. Static field variables come into existence when
the class in which they are declared is loaded. Static field variables exist until their associated class is
unloaded.

Declaring and Using Methods

Methods are declared using the following syntax:

modifiers returnValue methodName(parameterList) throwsClause {

// Method body

}
A method may have any access modifier (public, protected, private, or package access) or the
special modifiers (abstract, final, native, static, or synchronized). The use of these
modifiers is covered later in this chapter.

The return type of a method may be any of the following:

.
void—The method does not return a value.
.
A primitive type—The primitive types boolean, byte, char, short, int, long, float,
and double may be used as a method return type. The method must return a value that is
promotable (refer to Chapter 3, "Operators and Assignments") to the specified return type.
.
Object type—A method can return a reference to an object of any class or interface.
.
Array type—Even though arrays are Java objects, I'll list them separately just to make sure
they are not overlooked. A method may return a reference to any Java array. The return type
is specified as the array type. For example, suppose the test() method returns an array of
arrays of String objects. You could write its return type as String[][].
A method's parameter list is a comma-separated list of parameter declarations. Each parameter
declaration identifies the parameter's type and a name by which the parameter can be referenced. A
parameter may be referenced anywhere within the method. A parameter may also be declared as
final so that it may be accessed from within a local inner class. The use of final with method
parameters is covered in Chapter 6.
The throws clause of a method identifies all of the checked exception types that may be thrown (and
not caught) during the execution of a method. This includes methods that are thrown by other methods
invoked by the method. If a method throws (and does not catch) an exception of a particular type, the
throws clause must identify a type which is a superclass of the exception type (and a subclass of
java.lang.Throwable). The throws clause consists of a comma-separated list of checked
exception types. Exception throwing is covered in more detail in Chapter 5, "Flow Control and Exception
Handling."

Methods are used by invoking them with respect to an object reference. Methods are invoked using the
following syntax:

variable.methodName(argumentList)

- 64



Note
Method Signature A method's signature consists of the method name and the
sequence of types used to declare the method's parameters. It is illegal for a
class to declare two methods with the same signature.

The keywords this and super may be used instead of a variable name.
Static methods (covered later in this chapter) are methods which apply to the class as a whole rather
than an instance of a class. Static methods may be invoked using the same notation as non-static
methods. However, since static methods are not associated with an instance of a class, it is more
appropriate to invoke them using the class name rather than a variable name. The StaticMethod
program shown in Listing 4.2 illustrates this point. It invokes the staticdisplay() method of
StaticClass using the method invocation StaticClass.display("sample output").

Listing 4.2: The Staticmethod Program


class StaticMethod {
public static void main(String[] args) {
StaticClass.display("sample output");

}
}
class StaticClass {

static void display(String s) {
System.out.println("StaticClass: "+s);
}

}
Passing Arguments

An argument that is passed to a method may be a primitive value or an object reference. When a
primitive value is passed to a method, a copy of the value is made, and the copy is made available to
the method. The original value is not modified as the result of any changes to the argument that occurs
within the body of the method. The PassedValue program of Listing 4.3 illustrates this point. It displays
a value of 100 as its output. The value of i is not modified by the modifyMethod() method.

Listing 4.3: The Passedvalue Program


class PassedValue {

public static void main(String args[]) {
int i = 100;
modifyMethod(i);
System.out.println(i);

}

- 65



static void modifyMethod(int i)
{
i = i * 2;
}


}
When an object is passed as an argument to a method, a copy of the object reference (but not the
object itself) is made, and the copied object reference is passed to the method. Changes to the object
reference that occur during the method's execution do not affect the original object reference. However,
changes to the object itself that occur during the method's execution are made to the original object.
The PassedReference program of Listing 4.4 illustrates this distinction. The modifyReference()
method has no effect on the Vector v declared that is in main() since it changes the object's
reference. However, modifyReferencedObject() does have an effect on the Vector v that is
declared in main() because it modifies the contents of the vector.

Listing 4.4: The Passedreference Program


import java.util.*;

class PassedReference {

public static void main(String args[]) {
Vector v = new Vector();
v.add(new String("a"));
v.add(new String("b"));
v.add(new String("c"));
System.out.println(v);
modifyReference(v);
System.out.println(v);
modifyReferencedObject(v);
System.out.println(v);

}

static void modifyReference(Vector v) {
v = new Vector();
v.add(new String("1"));
v.add(new String("2"));
v.add(new String("3"));

- 66



}

static void modifyReferencedObject(Vector v) {

v.removeAllElements();

v.add(new String("1"));

v.add(new String("2"));

v.add(new String("3"));

}

}

Declaring Initializers

Java classes may contain statements that support the initialization of program variables. Initialization is
typically performed when a field variable is declared. Variable initializers are executed when a new
instance of a class is created. Other initializers, referred to as static initializers, are used to initialize
static variables. Static initializers are covered later in this chapter in the "Static" section.

Access Modifiers

Access modifiers are an important part of any declaration that can be accessed outside the class or
package in which it is made. Access modifiers enable you to determine whether a declaration is limited
to a particular class, a class and its subclasses, a package, or if it is freely accessible. Although access
modifiers are not iron-clad security controls, they can be used to limit access to your classes, interfaces,
variables, methods, and constructors.
Java provides three access modifiers (public, protected, and private) and a fourth default access
(package access). These modifiers are used as follows:

.
public—Enables a class or interface to be accessed outside of its package. It also enables
a variable, method, or constructor to be accessed anywhere its class may be accessed.
.
protected—Enables a variable, method, or constructor to be accessed by classes or
interfaces of the same package or by subclasses of the class in which it is declared.
.
private—Prevents a variable, method, or constructor from being accessed outside of the
class in which it is declared.
.
Package access—Package access occurs when public, protected, or private are not
specified. Package access applies to classes, interfaces, variables, methods, and
constructors. It allows the declared item to be accessed by any class or interface of the
same package.
Table 4.1 identifies the language elements that may be declared using the above access modifiers and
the restrictions that are placed on these language elements as the result of these modifiers.

Table 4.1: Access Modifiers

Modifier
public
Applies to
Classes
Interfaces
Field Variables
Methods
Constructors
Inner classes
Description
A class may be accessed outside of its
package.
An interface may be accessed outside of its
package.
A variable may be accessed anywhere that
its class may be accessed.
A method may be accessed anywhere that
its class may be accessed.
A constructor may be accessed anywhere
that its class may be accessed.
An inner class may be accessed anywhere

- 67



protected
private
(no access
modifier package
access)
Field variables
Methods
Constructors
Inner classes
Field variables
Methods
Constructors
Inner classes
Classes
Interfaces
Field variables
Methods
Constructors
Inner classes
that its class may be accessed.
A variable may be accessed by classes or
interfaces of the same package or by
subclasses of the class in which it is
declared.
A method may be accessed by classes or
interfaces of the same package or by
subclasses of the class in which it is
declared.
A constructor may only be accessed by
classes or interfaces of the same package or
by subclasses of the class in which it is
declared.
An inner class may only be accessed by
classes or interfaces of the same package or
by subclasses of the class in which it is
declared.
A variable may only be accessed within the
class in which it is declared.
A method may only be accessed within the
class in which it is declared.
A constructor may only be accessed within
the class in which it is declared.
An inner class may only be accessed within
the class in which it is declared.
A class may only be accessed within the
package in which it is declared.
An interface may only be accessed within the
package in which it is declared.
A variable may only be accessed within the
package in which it is declared.
A method may only be accessed within the
package in which it is declared.
A constructor may only be accessed within
the package in which it is declared.
An inner class may only be accessed within
the package in which it is declared.

Java's access modifiers support an important programming feature known as encapsulation.
Encapsulation allows access to a class to be restricted to a well-defined interface. Fully encapsulated
classes declare all of their field variables as private and provide access to the properties they
represent via special accessor methods. Encapsulation is covered in Chapter 6.

Note Friendly Access

Package access is also referred to as friendly access by old C++ programmers.

Other Modifiers

Java supports several other modifiers besides the access modifiers. These modifiers are covered in the
following subsections.
Note Access Modifiers and Inner Classes Access modifiers are also used with inner
classes. Inner classes are covered in Chapter 6.

- 68



abstract

The abstract modifier is used to identify abstract classes and methods. An abstract class defers
its implementation to its subclasses and may not be instantiated.

Note
Ordering Modifiers The order in which modifiers appear in a declaration is not
important. For example, staticfinal means the same thing as final
static.

Abstract classes may declare abstract methods. An abstract method is a method whose
implementation is deferred. The body of an abstract method is replaced by a semicolon. The
AbstractClass shown in Listing 4.5 is an abstract class that declares several abstract methods.

Listing 4.5: The Abstractclass Class


abstract class AbstractClass {
abstract void method1();
abstract String method2(Object obj) throws java.io.IOException;
abstract int method3(long l);
abstract boolean method4();

}
Note abstract and final Neither abstract classes nor abstract methods may be
declared as final.
Note abstract Subclasses If a class extends an abstract class then it must
implement all methods declared as abstract, if any, or be declared as
abstract, too.
final

The final modifier is used to indicate that a declared item may not be changed. When it is used with
a
class, it prevents the class from being extended (subclassed). When it is used with a field variable, it
indicates that the variable may not be modified after it has been assigned a value. Final variables are
used to create constants.
Local variables and method parameters may also be declared as final to enable them to be accessed
by local inner classes. The use of final with local variables is covered in Chapter 6.
When the final modifier is used with a method, it indicates that the method may not be overridden.
Chapter 6 covers method overriding.


native

The native modifier is used to identify a native method declaration. native methods are methods
that are written in code other than Java. The Java Native Interface (JNI) allows Java programs to
access native methods that are made available as shared dynamic link libraries. native methods are
declared using the following syntax:


modifiers native returnType methodName(parameterList) throwsClause
;
Note that the method body is replaced by a semicolon in the same manner as an abstract method.
However, native methods may not be declared as abstract.


static

The static modifier is used to indicate that a variable, method, or initializer applies to a class as a
whole instead of specific instances of the class. static variables are shared by all instances of a
class. Suppose that v is a static variable of class C, and c1 and c2 are variables that reference
instances of C. Then v may be accessed as c1.v, c2.v, and C.v. Because static variables are
shared by all instances of a class, c1.v, c2.v, and C.v all refer to the same value or object.
static methods are used to access the static variables of a class. They may also be used to invoke
other static methods. However, static methods may not be used to access non-static variables
or methods without specifying the class instance that the variable or method is associated with.
Because static methods are not associated with an object instance, they may not refer to the current

- 69



instance via the this identifier. The main() method of every Java application program is static. It is
invoked before an instance of the application class is created.
Static initializers are used to perform processing when a class is first loaded. As such, static
initializers are executed only once. Static initializers are identified by the static keyword followed by
code that is surrounded in curly brackets.

Note Non-static Methods and static Variables Non-static methods may

access both static and non-static variables.
The StaticApp program shown in Listing 4.6 illustrates the use of static variables, methods, and
initializers. The static initializer is executed upon loading of the StaticApp class. This occurs before
main() is executed. The s field variable is static and the t field variable is non-static. The
display(s) statement invokes the staticdisplay() method with the static variable s. The
app.display(app.t) statement invokes display() with the non-statict variable. The instance
of StaticApp to which tapplies (as in, app.t) must be supplied or else a compilation error results.

StaticappListing 4.6: The Program

class StaticApp {
static String s = "This code is executed second.";
String t = "This code is executed last.";
static { // Static initializer

display("This code is executed first.");
}
public static void main(String[] args) {

display(s)
;
StaticApp app = new StaticApp()
;
app.display(app.t)
;


}
static void display(String s) {
System.out.println(s);
}

}
synchronized

The synchronized modifier is used to control access to objects that are shared among multiple
threads. It is covered in Chapter 8, "Threads."

transient

The transient modifier is used with variables. It indicates that a variable may not be serialized. It is
typically used to reduce the possibility that an object containing sensitive data might be written to a
stream. A transient variable may not be declared as final or static.

volatile

The volatile modifier is used with variables. It is used to indicate that a variable may be modified
asynchronously in a multiprocessor environment. This modifier is rarely used and not covered on the

- 70



certification exam. However, it is good programming practice to use it with variables that may be
accessed by several threads without synchronization.

Chapter Summary

This chapter covers variable and method declarations and the use of modifiers in these declarations.
You learned the difference between field and local variables, how to declare and initialize arrays, and
how methods are declared and used. You also learned how arguments are passed to methods, how
access modifiers are used to restrict access to declared items, and how other modifiers are used. The
following review and exam questions will test your knowledge of these topics and will help you to
determine whether you need to study them further in preparation for the certification exam.

Key Terms

.. Declaration
.
Field variable
.
Local variable
.. Array
.
this
.
super
.. Method
.
void
.
public
.
protected
.
private
.
package access
.
static
.
final
.
abstract class
.
abstract method
.
native method
.
transient variable
Review Questions

1. What is the difference between a field variable and a local variable?
2. What is the difference between static and non-static variables?
3. How are this and super used?
4. What is a void return type?
5. If a class is declared without any access modifiers, where may the class be accessed?
6. If a variable is declared as private, where may the variable be accessed?
7. If a method is declared as protected, where may the method be accessed?
8. What is an abstract method?
9. What is a native method?
10. What is a transient variable?
Exam Questions

1. What is the output of the following program?
2. class Question extends SuperClass {
3. String s = "this";
4. public static void main(String[] args) {
5. new Question();
6. }
7. Question() {
8. super.display(s);
9. }
10. void display(String s) {
11. System.out.println("this: "+s);
- 71



12. }
13. }
14. class SuperClass {
15. String s = "super";
16. void display(String s) {
17. System.out.println("super: "+s);
18.
}
}
A.
this: this
B.
super: this
C.
this: super
D.
super: super
19. Which of the following declare an array of String objects?
A.
String[] s;
B.
String []s;
C.
String [s];
D.
String s[];
20. What is the value of a[3] as the result of the following array declaration?
int[] a = {1,2,3,4,5};

A.
1
B.
2
C.
3
D.
4
21. Which of the following are true about this method declaration?
22. void myMethod(String s) {
}

A.
myMethod() is static.
B.
myMethod() does not return a value.
C.
myMethod() is abstract.
D.
myMethod() may not be accessed outside of the package in which it is
declared.
23. Which of the following are true about this variable declaration?
private static int i = 3;

A.
The value of i may not be changed after it is assigned a value.
B.
i may only be updated by a static method.
C.
The value of i is shared among all instances of the class in which it is
declared.
D.
i may only be accessed within the class in which it is declared.
24. What is wrong with the following program?
25. class Question {
26. String s = "abc";
27. public static void main(String[] args) {
28. System.out.println(s);
29. }
}

A.
Nothing is wrong with the program.
B.
main() cannot be declared public because Question is not public.
C. Because main() is static, it may not access non-static swithout a
reference to an instance of Question.
D. The main() argument list is incorrect.
30. Which of the following are true?
A.
A top-level class may be declared as private.
B.
A method may be declared as transient.
C.
A constructor may be declared as volatile.
- 72



D. A local variable may be declared as final.
31. What is the output of the following program?
32. class Question {
33. static int i = 1;
34. static {
35. ++i;
36. }
37. public static void main(String[] args) {
38. increment(i,5);
39. display(i);
40. }
41. static void increment(int n, int m) {
42. n += m;
43. }
44. static void display(int n) {
45. System.out.print(n);
46. }
47. static {
48. ++i;
49.
}
}
A. 1
B. 3
C. 6
D. 7
50. Which of the following are true?
A. Local variables may be declared final.
B. Methods may be declared final.
C. Constructors may not be declared private.
D. transient variables may not be serialized.
51. What is the output of the following program?
52. class Question {
53. static int i = 1, j = 2;
54. static {
55. display(i);
56. }
57. public static void main(String[] args) {
58. display(j);
59. }
60. static void display(int n) {
61. System.out.print(n);
62.
}
}
A. 1
B. 2
C. 12
D. 21
- 73



Answers to Review Questions

1.
A field variable is a variable that is declared as a member of a class. A local variable is a
variable that is declared local to a method.
2.
A static variable is associated with the class as a whole rather than with specific
instances of a class. Non-static variables take on unique values with each object
instance.
3.
this is used to refer to the current object instance. super is used to refer to the
variables and methods of the superclass of the current object instance.
4.
A void return type indicates that a method does not return a value.
5.
A class that is declared without any access modifiers is said to have package access.
This means that the class can only be accessed by other classes and interfaces that are
defined within the same package.
6.
A private variable may only be accessed within the class in which it is declared.
7.
A protected method may only be accessed by classes or interfaces of the same
package or by subclasses of the class in which it is declared.
8.
An abstract method is a method whose implementation is deferred to a subclass.
9.
A native method is a method that is implemented in a language other than Java.
10. A transient variable is a variable that may not be serialized.
Answers to Exam Questions

1.
B. The display() method of SuperClass is invoked to display the s variable of
Question.
2.
A, B and D. The identifier name may not be enclosed in brackets.
3.
D. Array indices begin with 0.
4.
B and D. myMethod() does not return a value and is declared with package access.
5.
C and D. Because i is static it is shared among all instances of its class. Because i
is private it may only be accessed within the class in which it is declared.
6.
C. The non-static s variable may only be accessed with a reference to a Questionobject.
7.
D. A local variable may be declared as final. Only variables may be declared as
volatile or final. Top-level classes may not be private.
8.
B. Both static initializers are executed before main() is executed. The
increment() method has no effect on the value of i.
9.
A, B, and D. Constructors may be declared as final.
10. C. The static initializer is executed followed by main().

No comments: