Nested Classes 2
Nested Classes 2
Question 1
class Z {
static class F {} // 1
synchronized class G {} // 2
transient class H {} // 3
volatile class I {} // 4
}
a. 1
b. 2
c. 3
d. 4
e. None of the above
ANSWER
Please note that this question asks which class declaration does
NOT result in a compile-time error. The following modifiers can
be applied to a member class: abstract, private, protected, public,
1 a 1 static and final. The synchronized modifier can not be applied to
any class, because it is a method modifier. The modifiers,
transient and volatile, can not be applied to any class, because
they are field modifiers.
Question 2
class Z {
void m1() {
abstract class A {} // 1
final class B {} // 2
private class C {} // 3
protected class D {} // 4
public class E {} // 5
}
}
Which class declarations result in compile-time errors?
a. 1
b. 2
c. 3
d. 4
e. 5
ANSWER
c d 3 4 The abstract and final modifiers can be applied to a method local
2 class declaration.
e 5
Question 3
class Z {
void m1() {
static class F {} // 1
synchronized class G {} // 2
transient class H {} // 3
volatile class I {} // 4
abstract class A {} // 5
final class B {} // 6
}
}
a. 1
b. 2
c. 3
d. 4
e. 5
f. 6
ANSWER
a 1 The modifiers, abstract and final, can be applied to a method local class
b 2 declaration. The synchronized modifier can not be applied to a class,
3
c 3 because it is a method modifier. The modifiers, transient and volatile, can
d 4 not be applied to any class, because they are field modifiers.
Question 4
class A {
A() {} // 1
int A; // 2
void A() {} // 3
class A {} // 4
}
a. 1
b. 2
c. 3
d. 4
e. None of the above
ANSWER
A method and a field can share the same name, because they are used in
different contexts and use different lookup procedures. They can even share
the same name with the class in which they are declared. Please note that
4 d 4 class names usually begin with an upper case letter while method and field
names usually begin with a lower case letter. A nested class can not share the
same name with its enclosing class.
Question 5
class A {
int B; // 1
void B() {} // 2
class B {} // 3
}
a. 1
b. 2
c. 3
d. None of the above
ANSWER
A method, field, and a nested class can share the same name, because
they are used in different contexts and use different lookup
procedures. Please note that class names usually begin with an upper
None of case letter while method and field names usually begin with a lower
5 d the case letter. Also note that a nested class can not share the same name
above with its enclosing class; however, a method and field can share a
name with the enclosing class. Even so, it is not a good idea to name
a method with the name of the enclosing class, because it could be
confused with a constructor.
Question 6
abstract class A { // 1
private abstract void m1(); // 2
private abstract class B {} // 3
private class C extends B {} // 4
}
a. 1
b. 2
c. 3
d. 4
e. None of the above.
ANSWER
An abstract method has no implementation, and is not useful until an
extending class implements the method. Private methods are not inherited
and can not be overridden. If an abstract method is declared private, then it
6 b 2 can not be implemented in a subclass. Although a method may not be both
private and abstract, a nested class can be; because another nested class can
extend the abstract class and implement any abstract methods.
Question 7
abstract class A { // 1
abstract final void m1(); // 2
abstract final class B {} // 3
class C extends B {} // 4
}
a. 1
b. 2
c. 3
d. 4
e. None of the above
ANSWER
Please note that this question asks which line does NOT result in a
compile-time error. An abstract method has no implementation and is not
useful until an extending class implements the method. A final method can
not be overridden by a subclass method. An abstract final method can not be
7 a 1 implemented and is not legal. An abstract class may contain abstract method
declarations and is assumed to be incomplete. A final class can not be
extended. The implementation of an abstract final class could not be
completed. The declaration of class C results in a compiler error, because a
final class may not be listed in the extends clause.
Question 8
abstract class A { // 1
abstract synchronized void m1(); // 2
abstract synchronized class B {} // 3
synchronized class C extends B {} // 4
}
a. 1
b. 2
c. 3
d. 4
e. None of the above
ANSWER
8 a 1 Please note that this question asks which line does NOT result in a
compile-time error. The modifier, synchronized, is a method modifier, but is
not a class modifier. Any attempt to declare a synchronized class results in a
compile-time error. Since the synchronized modifier specifies an
implementation detail it makes no sense to use it with an abstract method that
provides no implementation.
Question 9
class G {
final String s1 = "G.s1";
class Z {
String s1;
void m1() {System.out.println(???);}
}
public static void main(String args[]) {
G g = new G(); g.new Z().m1();
}}
a. s1
b. G.s1
c. ((G)this).s1
d. G.this.s1
e. G.super.s1
f. None of the above
ANSWER
The qualified this expression
9 d G.this.s1 ClassName.this.name can be used to access shadowed
variables declared within an enclosing class.
Question 10
class A {
private static int f1 = 1;
private int f2 = 2;
void m1(int p1, final int p2) {
int l1 = 5;
final int l2 = 6;
Object x = new Object() {
int a = f1; // 1
int b = f2; // 2
int c = p1; // 3
int d = p2; // 4
int e = l1; // 5
int f = l2; // 6
};}}
a. 1
b. 2
c. 3
d. 4
e. 5
f. 6
ANSWER
Local method variables and method parameters are stored on the
stack and go out of scope after the method is exited. Although a
local reference variable is stored on the stack, the referenced
object is stored on the heap; so the object can continue to exist
c 3
10 long after the method runs to completion. An object that is
e 5
instantiated within a method or block is not permitted to refer to
a variable that is declared within the method or block unless the
variable is declared final and the variable declaration precedes the
creation of the object.
Question 11
class Outer {
static class StaticNested {
static final int a = 25; // 1
static final int b; // 2
static int c; // 3
int d; // 4
static {b = 42;} // 5
}
class NonStaticInner {
static final int e = 25; // 6
static final int f; // 7
static int g; // 8
int h; // 9
static {f = 42;} // 10
}}
a. 1
b. 2
c. 3
d. 4
e. 5
f. 6
g. 7
h. 8
i. 9
j. 10
ANSWER
A non-static nested class is called an inner class. An inner
class can not declare a static field unless it is a compile-time
constant. Even though f is final, it does not have a value at
g
7 8 compile time; so it causes a compilation error. Member
11 h
10 variable g also causes a compile-time error, because it is
j
static. The static initializer of NonStaticInner causes a
compile-time error, because inner classes (i.e. non-static
nested classes) can not declare static initializers.
Question 12
class Red {
private static final int a = 10; // 1
protected static int b = 20; // 2
int c = 30; // 3
static class StaticNested {
int d = a; // 4
int e = b; // 5
int f = c; // 6
}
class NonStaticInner {
int g = a; // 7
int h = b; // 8
int i = c; // 9
}}
a. 1
b. 2
c. 3
d. 4
e. 5
f. 6
g. 7
h. 8
i. 9
ANSWER
The non-static members of an enclosing class are not directly
available to a static nested class. From within StaticNested, the
non-static members of the enclosing class can not be referred to
by a simple name. Instead, a qualified name is required. Suppose
12 f 6
a reference variable r1 refers to an instance of the enclosing class
Red. Then the instance member c of the enclosing class instance
referenced by r1 could be accessed using the qualified name r1.c.
Question 13
class Red {
static class StaticNested {interface ABC {}} //
1
class NonStaticInner {interface DEF {}} //
2
interface GHI {} //
3
}
a. 1
b. 2
c. 3
d. None of the above
ANSWER
A member interface is implicitly static; therefore, it can not be declared as a
13 b 2 member of a non-static nested class
Question 14
class A {
private static int counter;
public static int getCounter(){return counter++;}
private static int innerCounter;
public static int getInnerCounter(){return
innerCounter++;}
private String name;
A() {name = "A" + getCounter();}
class B {
private String name;
B() {
name = "B" + getInnerCounter();
System.out.print(A.this.name + name); // 1
}}
public static void main(String[] args) {
new A().new B(); // 2
A a1 = new A();
a1.new B(); // 3
a1.new B(); // 4
}}
ANSWER
14 a Prints: Class A is the enclosing class of the inner class
A0B0A1B1A1B2 B. An instance of class B must be associated
with an enclosing instance of class A. In a static
context such as the main method, instantiation
of a named inner class requires the use of a
qualified class instance creation expression of
the form Reference.new
Identifier(ArgumentListopt). The
reference could be provided by a reference
variable of the type of the enclosing class, or it
could be provided by another class instance
creation expression. At line 2, the qualified class
instance creation expression new A().new
B() first creates a new instance of the enclosing
class A, then it creates an instance of B. The
new instance of A is the first instance created; so
the name is A0. The new instance of B is the
first instance created; so the name is B0. At line
3, the qualified class instance creation
expression a1.new B() creates an instance of
B that is associated with a previously existing
instance of class A that is referenced by variable
a1. The instance of class A referenced by
variable a1 is the second instance created so the
name is A1. The new instance of B is the second
instance created; so the name is B1. At line 4, a
new instance of B is created and associated with
the instance of A this is referenced by variable
a1.
Question 15
class A {
private static int counter;
public static int getCounter(){return counter++;}
private static int innerCounter;
public static int getInnerCounter(){return
innerCounter++;}
private String name;
A() {name = "A" + getCounter();}
class B {
private String name;
B() {
name = "B" + getInnerCounter();
System.out.print(A.this.name + name); // 1
}}
void m1() {new A().new B();} // 2
void m2() {this.new B();} // 3
void m3() {new B();} // 4
public static void main(String[] args) {
A a1 = new A();
a1.m1(); a1.m2(); a1.m3();
}}
a. Prints: A0B0A1B1A1B2
b. Prints: A0B0A1B1A2B2
c. Prints: A1B0A0B1A0B2
d. Compile-time error at line 1
e. Compile-time error at line 2
f. Compile-time error at line 3
g. Compile-time error at line 4
h. Other compile-time error.
i. Run-time error
j. None of the above
ANSWER
15 c Prints: Class A is the enclosing class of the inner class
A1B0A0B1A0B2 B. An instance of class B must be associated
with an enclosing instance of class A. In a static
context, instantiation of a named inner class
requires the use of a qualified class instance
creation expression of the form
Reference.new
Identifier(ArgumentListopt). The
reference could be provided by a reference
variable of the type of the enclosing class, or it
could be provided by another class instance
creation expression. If the enclosing class is not
an inner class, then the enclosing class could be
instantiated with an unqualified class instance
creation expression such as the following, new
EnclosingClass(). The qualified class
instance creation expression new A().new
B() first creates a new instance of A, then it
creates an instance of B. The new instance of A
is the second instance created; so the name is
A1. The new instance of B is the first instance
created; so the name is B0. In the qualified class
instance creation expression this.new B(),
the keyword this, denotes a reference to the
enclosing instance on which the method m2 has
been invoked. A new instance of the enclosing
class is not created; so the name of the enclosing
instance is A0. The new instance of B is the
second instance created; so the name is B1.
Since method m3 is an instance method, the
inner class B can be instantiated using the
unqualified class instance creation expression
new B(). The enclosing instance is the
instance on which the method m3 has been
invoked. It is the same instance that is
referenced by the keyword this and the
reference variable a1.
Question 16
class A {
private static int counter;
public static int getCounter(){return counter++;}
private static int innerCounter;
public static int getInnerCounter(){return
innerCounter++;}
private String name;
A() {name = "A" + getCounter();}
class B {
private String name;
B() {
name = "B" + getInnerCounter();
System.out.print(A.this.name + name);
}}
void m1() {new A().new B();} // 1
void m2() {new A.B();} // 2
void m3() {new B();} // 3
public static void main(String[] args) {
A a1 = new A();
a1.m1(); a1.m2(); a1.m3();
}}
a. Prints: A0B0A1B1A1B2
b. Prints: A0B0A1B1A2B2
c. Prints: A1B0A0B1A0B2
d. Compile-time error at line 1
e. Compile-time error at line 2
f. Compile-time error at line 3
g. Compile-time error at line 4
h. Other compile-time error.
i. Run-time error
j. None of the above
ANSWER
16 c Prints: Class A is the enclosing class of the inner class
A1B0A0B1A0B2 B. An instance of class B must be associated
with an enclosing instance of class A. In a static
context, instantiation of a named inner class
requires the use of a qualified class instance
creation expression of the form
Reference.new
Identifier(ArgumentListopt). The
reference could be provided by a reference
variable of the type of the enclosing class, or it
could be provided by another class instance
creation expression. If the enclosing class is not
an inner class, then the enclosing class could be
instantiated with an unqualified class instance
creation expression such as the following, new
EnclosingClass(). At line 1, the qualified
class instance creation expression new
A().new B() first creates a new instance of
A, then it creates an instance of B. The new
instance of A is the second instance created; so
the name is A1. The new instance of B is the
first instance created; so the name is B0. At line
2, a new instance of the named inner class B is
created using the class instance creation
expression new A.B(). The fully qualified
name of class B is A.B. Since the class instance
creation expression new A.B() appears
within a method that is a member of class A, the
use of the fully qualified name is unnecessary.
Within method A.m2, the class instance creation
expression new A.B() could be replaced by
the expression new B() without changing the
result. Using either expression, a new instance
of class B is created without creating a new
instance of class A. Instead, the new instance of
class B is associated with the same instance of
class A on which the method m2 has been
invoked. It is the same instance of class A that is
referenced by the keyword this and the
reference variable a1. Since it was the first
instance created, the name is A0. The new
instance of B is the second instance created; so
the name is B1. At line 3, a new instance of the
named inner class B is created using the
unqualified class instance creation expression
new B(). The new instance of B is the third
instance created; so the name is B2. The new
instance of the inner class is associated with the
same instance of the enclosing class on which
the method m3 has been invoked. It is the same
instance that is referenced by the keyword
this and the reference variable a1. Since it
was the first instance created, the name is A0
Question 17
class A {
private static int counter;
public static int getCounter(){return counter++;}
private static int innerCounter;
public static int getInnerCounter(){return
innerCounter++;}
private String name;
A() {name = "A" + getCounter();}
class B {
private String name;
B() {
name = "B" + getInnerCounter();
System.out.print(A.this.name + name); // 1
}}
static void m1() {new A().new B();} // 2
static void m2() {this.new B();} // 3
static void m3() {new B();} // 4
public static void main(String[] args) {
m1(); m2(); m3();
}}
What are the results of attempting to compile and run the program?
a. Prints: A0B0A1B1A1B2
b. Prints: A0B0A1B1A2B2
c. Prints: A1B0A0B1A0B2
d. Compile-time error at line 1
e. Compile-time error at line 2
f. Compile-time error at line 3
g. Compile-time error at line 4
ANSWER
17 f Compile- Class A is the enclosing class of the inner class B. An
g time error at instance of class B must be associated with an
line 3 enclosing instance of class A. In a static context,
Compile- instantiation of a named inner class requires the use of
time error at a qualified class instance creation expression of the
line 4 form Reference.new
Identifier(ArgumentListopt). The reference
could be provided by a reference variable of the type
of the enclosing class, or it could be provided by
another class instance creation expression. If the
enclosing class is not an inner class, then the enclosing
class could be instantiated with an unqualified class
instance creation expression such as the following,
new EnclosingClass(). The qualified class
instance creation expression new A().new B()
first creates a new instance of A, then it creates an
instance of B. The qualified class instance creation
expression this.new B() generates a compile-
time error, because the keyword this can not be used
within a static method. Since methods m1, m2 and m3
are static methods, an instance of the named inner
class B can not be created inside any of the three
methods using an unqualified class instance creation
expression of the form new
ClassType(ArgumentListopt).
Question 18
abstract class A {
private int x = 4, y = 2;
public A(int i1, int i2) {x=i1;y=i2;}
public int x() {return x;}
public void x(int x) {this.x = x;}
public int y() {return y;}
public void y(int y) {this.y = y;}
public abstract int math();
}
class B {
static A a1 = new A(2,1) {public int math()
{return x()+y();}};
static A a2 = new A(2,1) {public int math()
{return x()-y();}};
static A a3 = new A(2,1) {public int math()
{return x()*y();}};
static A a4 = new A(2,1) {public int math()
{return x()/y();}};
public static void main(String[] args) {
System.out.print("" + a1.math() + a2.math() +
a3.math() + a4.math());
}}
a. Prints: 8
b. Prints: 3122
c. Compile-time error
d. Run-time error
e. None of the above
ANSWER
The arguments that appear in the class instance creation
Prints:
18 b expression of an anonymous class are passed to a
3122
constructor of the superclass.