You are on page 1of 27

Inner Classes

Exam Objectives
‡ :ULWHFRGHWRFRQVWUXFWLQVWDQFHVRIDQ\FRQFUHWHFODVVLQFOXGLQJQRUPDO
WRSOHYHOFODVVHVLQQHUFODVVHVVWDWLFLQQHUFODVVHVDQGDQRQ\PRXVLQQHU
FODVVHV

Supplementary Objectives
‡ 6WDWHWKHNLQGVRIQHVWHGFODVVHVDQGLQWHUIDFHVWKDWFDQEHGHILQHG
‡ ,GHQWLI\WKHFRQWH[WLQZKLFKDQHVWHGFODVVRULQWHUIDFHFDQEHGHILQHG
‡ 6WDWHZKLFKDFFHVVLELOLW\PRGLILHUVDUHDOORZHGIRUHDFKFDWHJRU\RIQHVWHG
FODVVHV
‡ 6WDWHZKLFKQHVWHGFODVVHVFUHDWHLQVWDQFHVWKDWDUHDVVRFLDWHGZLWKLQVWDQFHV
RIWKHRXWHUFRQWH[W
‡ 6WDWHWKHDFFHVVUXOHVWKDWJRYHUQDFFHVVLQJHQWLWLHVLQWKHRXWHUFRQWH[WRI
QHVWHGFODVVHVDQGZULWHFRGHWKDWXVHVWKHDXJPHQWHGV\QWD[LQYROYLQJWKH
thisNH\ZRUGIRUWKLVSXUSRVH
‡ 6WDWHZKHWKHUDGHILQLWLRQRIDQHVWHGFODVVFDQFRQWDLQVWDWLFDQGQRQVWDWLF
PHPEHUV
‡ :ULWHFRGHWRLQVWDQWLDWHQHVWHGFODVVHVXVLQJWKHDXJPHQWHGV\QWD[RIWKH
newRSHUDWRU
‡ :ULWHFRGHWRVKRZKRZQHVWHGFODVVHVFDQEHLPSRUWHGDQGXVHG
‡ 'LVWLQJXLVKEHWZHHQWKHLQKHULWDQFHDQGFRQWDLQPHQWKLHUDUFK\RIDQ\
QHVWHGFODVVRULQWHUIDFH
‡ :ULWHFRGHWRLPSOHPHQWDQRQ\PRXVFODVVHVE\H[WHQGLQJDQH[LVWLQJFODVV
DQGE\LPSOHPHQWLQJDQLQWHUIDFH

223
224 CHAPTER 7: INNER CLASSES

7.1 Overview of Nested Classes


$QRUGLQDU\FODVVRULQWHUIDFHLVGHILQHGDWWKHWRSOHYHOZKLFKLVWKHSDFNDJHOHYHO
7KHVHFODVVHVDQGLQWHUIDFHV DOVRFDOOHGWRSOHYHOSDFNDJHPHPEHUFODVVHVRULQWHUIDFHV
DUHJURXSHGLQWRSDFNDJHV,QDGGLWLRQWRWKHVHWRSOHYHOSDFNDJHPHPEHUFODVVHV
DQGLQWHUIDFHVWKHUHDUHIRXUFDWHJRULHVRIQHVWHGFODVVHVDQGRQHRIQHVWHGLQWHUIDFHV
GHILQHGE\WKHFRQWH[WWKHVHFODVVHVDQGLQWHUIDFHVDUHGHFODUHGLQ
‡ 7RSOHYHO1HVWHG&ODVVHVDQG,QWHUIDFHV
‡ 1RQVWDWLF,QQHU&ODVVHV
‡ /RFDO&ODVVHV
‡ $QRQ\PRXV&ODVVHV
7RSOHYHOQHVWHGFODVVHVDQGLQWHUIDFHVDUHDOVRFRQVLGHUHGWREHDWWKHWRSOHYHO7KH
ODVWWKUHHFDWHJRULHVDUHFROOHFWLYHO\NQRZQDVLQQHUFODVVHV7KHVHGLIIHUIURPWRS
OHYHOFODVVHVLQWKDWWKH\FDQXVHVLPSOHQRQVWDWLFQDPHVIURPWKHHQFORVLQJFRQWH[W
LHDQLQVWDQFHRIDQLQQHUFODVVLVQRWOLPLWHGWRGLUHFWO\DFFHVVLQJRQO\LWVRZQ
LQVWDQFHYDULDEOHV,QSDUWLFXODUDQLQVWDQFHRIDQLQQHUFODVVPD\EHDVVRFLDWHG
ZLWKDQLQVWDQFHRIWKHHQFORVLQJFODVVDQGPD\DFFHVVLWVPHPEHUV
$WRSOHYHOQHVWHGFODVVRULQWHUIDFHLVGHILQHGDVDstaticPHPEHULQDWRSOHYHO SRVV
LEO\ QHVWHG  FODVV RU LQWHUIDFH 6XFK D QHVWHG FODVV FDQ EH LQVWDQWLDWHG OLNH DQ\
RUGLQDU\WRSOHYHOFODVVXVLQJLWVIXOOQDPH1RLQVWDQFHRIWKHHQFORVLQJFODVVLV
UHTXLUHGWRLQVWDQWLDWHDWRSOHYHOQHVWHGFODVV1RQVWDWLFLQQHUFODVVHVDUHGHILQHG
DV LQVWDQFH PHPEHUV RI RWKHU FODVVHV MXVW OLNH LQVWDQFH YDULDEOH DQG PHWKRG
PHPEHUVDUHGHILQHGLQDFODVV$QLQVWDQFHRIDQRQVWDWLFLQQHUFODVVDOZD\VKDV
DQLQVWDQFHRIWKHHQFORVLQJFODVVDVVRFLDWHGZLWKLW/RFDOFODVVHVFDQEHGHILQHGLQ
DEORFNRIFRGHDVLQDPHWKRGERG\RUDORFDOEORFNMXVWDVORFDOYDULDEOHVFDQEH
GHILQHGLQDPHWKRGERG\RUDORFDOEORFN$QRQ\PRXVFODVVHVFDQEHGHILQHGDQG
LQVWDQWLDWHG´RQWKHIO\µLQH[SUHVVLRQV/RFDODQGDQRQ\PRXVFODVVHVFDQEHHLWKHU
VWDWLFRUQRQVWDWLFZKHUHEHLQJQRQVWDWLFPHDQVWKDWDQLQVWDQFHRIVXFKDFODVVLV
DVVRFLDWHGZLWKDQLQVWDQFHRIWKHHQFORVLQJFODVV
7DEOHSUHVHQWVDVXPPDU\RIYDULRXVDVSHFWVUHODWLQJWRFODVVHVDQGLQWHUIDFHV
7KH (QWLW\ FROXPQ OLVWV WKH GLIIHUHQW NLQGV RI FODVVHV DQG LQWHUIDFHV WKDW FDQ EH
GHILQHG7KH'HFODUDWLRQ&RQWH[WFROXPQOLVWVWKHOH[LFDOFRQWH[WLQZKLFKWKHFODVV
RU LQWHUIDFH FDQ EH GHILQHG 7KH $FFHVVLELOLW\ 0RGLILHUV FROXPQ LQGLFDWHV ZKDW
DFFHVVLELOLW\FDQEHVSHFLILHGIRUWKHFODVVRULQWHUIDFH7KH2XWHU,QVWDQFHFROXPQ
VSHFLILHV ZKHWKHU DQ LQVWDQFH RI WKH HQFORVLQJ FRQWH[W LV DVVRFLDWHG ZLWK DQ
LQVWDQFHRIWKHFODVV7KH'LUHFW$FFHVVWR(QFORVLQJ&RQWH[WFROXPQOLVWVZKDWLV
GLUHFWO\DFFHVVLEOHLQWKHHQFORVLQJFRQWH[WIURPZLWKLQWKHFODVV7KH'HILQHV6WDWLF
RU1RQVWDWLF0HPEHUVFROXPQUHIHUVWRZKHWKHUWKHFODVVFDQGHILQHVWDWLFRUQRQ
VWDWLFPHPEHUVRUERWK6XEVHTXHQWVHFWLRQVRQHDFKQHVWHGFODVVHODERUDWHRQWKH
VXPPDU\SUHVHQWHGLQ7DEOH 1$LQWKHWDEOHPHDQVQRWDSSOLFDEOH
SECTION 7.1: OVERVIEW OF NESTED CLASSES 225

1HVWHGFODVVHVFDQEHUHJDUGHGDVDIRUPRIHQFDSVXODWLRQHQIRUFLQJUHODWLRQVKLSV
EHWZHHQFODVVHVE\JUHDWHUSUR[LPLW\8VHGMXGLFLRXVO\WKH\FDQEHEHQHILFLDOEXW
XQUHVWUDLQHGQHVWLQJFDQHDVLO\UHVXOWLQLQFRPSUHKHQVLEOHFRGH

Table 7.1 Overview of Classes and Interfaces

(QWLW\ 'HFODUDWLRQ $FFHVV 2XWHU 'LUHFW$FFHVV 'HILQHV


&RQWH[W LELOLW\ ,QVWDQFH WR(QFORVLQJ 6WDWLFRU
0RGLILHUV &RQWH[W 1RQVWDWLF
0HPEHUV

3DFNDJH $VSDFNDJH publicRU 1R 1$ %RWKVWDWLF


OHYHOFODVV PHPEHU GHIDXOW DQG
QRQVWDWLF
7RSOHYHO $VVWDWLF DOO 1R 6WDWLFPHPEHUV %RWKVWDWLF
QHVWHGFODVV FODVV LQHQFORVLQJ DQG
VWDWLF PHPEHU FRQWH[W QRQVWDWLF
1RQVWDWLF $V DOO <HV $OOPHPEHUVLQ 2QO\
LQQHUFODVV QRQVWDWLF HQFORVLQJ QRQVWDWLF
FODVV FRQWH[W
PHPEHU
/RFDOFODVV ,QEORFN QRQH <HV $OOPHPEHUVLQ 2QO\
QRQVWDWLF ZLWK HQFORVLQJ QRQVWDWLF
QRQVWDWLF FRQWH[WORFDO
FRQWH[W ILQDOYDULDEOHV
/RFDOFODVV ,QEORFN QRQH 1R 6WDWLFPHPEHUV 2QO\
VWDWLF ZLWKVWDWLF LQHQFORVLQJ QRQVWDWLF
FRQWH[W FRQWH[WORFDO
ILQDOYDULDEOHV
$QRQ\PRXV $V QRQH <HV $OOPHPEHUVLQ 2QO\
FODVV H[SUHVVLRQ HQFORVLQJ QRQVWDWLF
QRQVWDWLF LQQRQ FRQWH[WORFDO
VWDWLF ILQDOYDULDEOHV
FRQWH[W
$QRQ\PRXV $V QRQH 1R 6WDWLFPHPEHUV 2QO\
FODVV H[SUHVVLRQ LQHQFORVLQJ QRQVWDWLF
VWDWLF LQVWDWLF FRQWH[WORFDO
FRQWH[W ILQDOYDULDEOHV
,QWHUIDFH $VSDFNDJH public RQO\ 1$ 1$ 6WDWLF
PHPEHURU YDULDEOHV
VWDWLFFODVV QRQVWDWLF
PHPEHU PHWKRG
SURWRW\SHV
226 CHAPTER 7: INNER CLASSES

7.2 Top-level Nested Classes and Interfaces


$WRSOHYHOQHVWHGFODVVRULQWHUIDFHLVVLPLODUWRDWRSOHYHOSDFNDJHPHPEHUFODVVRU
LQWHUIDFHEXWLWLVGHILQHGDVD staticPHPEHURIDQHQFORVLQJWRSOHYHOFODVVRU
LQWHUIDFH7RSOHYHOQHVWHGFODVVHVDQGLQWHUIDFHVFDQEHQHVWHGWRDQ\GHSWKEXW
RQO\ZLWKLQRWKHUVWDWLFWRSOHYHOFODVVHVDQGLQWHUIDFHV
,QWHUIDFHVDUHLPSOLFLWO\VWDWLF1HVWHGLQWHUIDFHVFDQRSWLRQDOO\EHSUHIL[HGZLWK
WKHNH\ZRUGstaticDQGKDYHDQ\DFFHVVLELOLW\7KHUHDUHQRQRQVWDWLFLQQHUORFDO
RUDQRQ\PRXVLQWHUIDFHV²RQO\ SRVVLEO\QHVWHG staticWRSOHYHOLQWHUIDFHV

Example 7.1 Top-level Nested Classes and Interfaces


// Filename: TopLevelClass.java
public class TopLevelClass { // (1)
// ...
static class NestedTopLevelClass { // (2)
// ...
interface NestedTopLevelInterface1 { // (3)
// ...
}
static class NestedTopLevelClass1
implements NestedTopLevelInterface1 { // (4)
// ...
}
}
}

,Q([DPSOHWKHWRSOHYHOSDFNDJHPHPEHUFODVVTopLevelClassDW  FRQWDLQVD
QHVWHGWRSOHYHOFODVVNestedTopLevelClassDW  ZKLFKLQWXUQGHILQHVDQHVWHGWRS
OHYHOLQWHUIDFHNestedTopLevelInterface1DW  ZKLFKLVLPSOHPHQWHGE\WKHQHVWHG
WRSOHYHOFODVV NestedTopLevelClass1DW  1RWHWKDWHDFKQHVWHGWRSOHYHOFODVVLV
GHILQHGDVstaticMXVWOLNHstaticYDULDEOHVDQGPHWKRGVLQDFODVV
7KHIXOOQDPHRIDQHVWHGWRSOHYHOFODVVRULQWHUIDFHLQFOXGHVWKHQDPHRIWKHFODVV
LW LV GHILQHG LQ )RU H[DPSOH WKH IXOO QDPH RI WKH QHVWHG WRSOHYHO FODVV Nested
TopLevelClass1 DW   LV TopLevelClass.NestedTopLevelClass.NestedTopLevelClass1
7KHIXOOQDPHRIWKHQHVWHGWRSOHYHOLQWHUIDFHNestedTopLevelInterface1DW  LVTop
LevelClass.NestedTopLevelClass.NestedTopLevelInterface1 1RWH WKDW HDFK QHVWHG
WRSOHYHOFODVVRULQWHUIDFHLVXQLTXHO\LGHQWLILHGE\WKLVQDPLQJFRQYHQWLRQZKLFK
LVDJHQHUDOL]DWLRQRIWKHIXOO\TXDOLILHGQDPLQJVFKHPHIRUSDFNDJHPHPEHUV7KH
IXOOFODVVQDPHFDQEHXVHGLQDSURJUDPOLNHDQ\RWKHUFODVVRULQWHUIDFHQDPH
1RWH WKDW D QHVWHG FODVV FDQQRW KDYH WKH VDPH QDPH DV DQ HQFORVLQJ FODVV RU
SDFNDJH
SECTION 7.2: TOP-LEVEL NESTED CLASSES AND INTERFACES 227

,IWKHILOHTopLevelClass.javaFRQWDLQLQJWKHGHILQLWLRQVLQ([DPSOHLVFRPSLOHG
LWZLOOUHVXOWLQWKHJHQHUDWLRQRIWKHIROORZLQJFODVVILOHVZKHUHHDFKILOHFRUUHV
SRQGVWRDFODVVRULQWHUIDFHGHILQLWLRQ
TopLevelClass$NestedTopLevelClass$NestedTopLevelClass1.class
TopLevelClass$NestedTopLevelClass$NestedTopLevelInterface1.class
TopLevelClass$NestedTopLevelClass.class
TopLevelClass.class

1RWHKRZWKHIXOOFODVVQDPHFRUUHVSRQGVWRWKHILOHQDPH PLQXVWKHH[WHQVLRQ
ZLWKWKHGROODUVLJQ $ UHSODFHGE\WKHGRWVLJQ . 
$FOLHQWFDQXVHWKHimportVWDWHPHQWWRSURYLGHDVKRUWFXWIRUWKHQDPHVRIQHVWHG
WRSOHYHOFODVVHVDQGLQWHUIDFHV+HUHDUHVRPHYDULDWLRQVRQXVDJHRIWKH import
VWDWHPHQWIRUQHVWHGWRSOHYHOFODVVHVDQGLQWHUIDFHV
// Filename: Client1.java
import TopLevelClass.*; // (1)

public class Client {


NestedTopLevelClass.NestedTopLevelClass1 objRef1 =
new NestedTopLevelClass.NestedTopLevelClass1(); // (2)
}

// Filename: Client2.java
import TopLevelClass.NestedTopLevelClass.*; // (3)
public class Client2 {
NestedTopLevelClass1 objRef2 = new NestedTopLevelClass1(); // (4)
}

class SomeClass implements


TopLevelClass.NestedTopLevelClass.NestedTopLevelInterface1 { // (5)
/* ... */
}

,QWKHILOHClient1.javaWKHimportVWDWHPHQWDW  DOORZVWKHQHVWHGWRSOHYHOFODVV
NestedTopLevelClass1WREHUHIHUHQFHGDV NestedTopLevelClass.NestedTopLevelClass1
DVDW  ZKHUHDVLQWKHILOHClient2.javaWKHimportVWDWHPHQWDW  ZLOODOORZWKH
VDPHFODVVWREHUHIHUHQFHGXVLQJWKHVLPSOHQDPHDVDW  $W  WKHIXOOQDPHRI
WKHQHVWHGWRSOHYHOLQWHUIDFHLVXVHGLQDQimplementsFODXVH
)RUDOOLQWHQWVDQGSXUSRVHVDWRSOHYHOQHVWHGFODVVRULQWHUIDFHLVYHU\PXFKOLNH
DQ\ RWKHU WRSOHYHO SDFNDJH PHPEHU FODVV RU LQWHUIDFH 6WDWLF YDULDEOHV DQG
PHWKRGVEHORQJWRDFODVVDQGQRWWRLQVWDQFHVRIWKHFODVV7KHVDPHLVWUXHIRU
QHVWHGWRSOHYHOFODVVHV$ VWDWLF QHVWHGWRSOHYHOFODVVFDQEHLQVWDQWLDWHGZLWK
RXWDQ\UHIHUHQFHWRDQ\LQVWDQFHRIWKHHQFORVLQJFRQWH[WLHREMHFWVRIDQHVWHG
WRSOHYHOFODVVFDQEHFUHDWHGZLWKRXWUHJDUGWRLWVQHVWLQJ([DPSOHVRIFUHDWLQJ
LQVWDQFHVRIQHVWHGWRSOHYHOFODVVHVDUHVKRZQDERYHDW  DQG  XVLQJWKH new
RSHUDWRU
6WDWLFPHWKRGVGRQRWKDYHD thisUHIHUHQFHDQGFDQWKHUHIRUHRQO\DFFHVVRWKHU
staticPHWKRGVDQGYDULDEOHVGLUHFWO\LQWKHFODVV7KLVDOVRDSSOLHVWRPHWKRGVLQ
228 CHAPTER 7: INNER CLASSES

D QHVWHG WRSOHYHO FODVV $ PHWKRG LQ D QHVWHG WRSOHYHO FODVV FDQ RQO\ GLUHFWO\
DFFHVVVWDWLFPHPEHUVLQWKHHQFORVLQJFODVVRULQWHUIDFHEXWQRWLQVWDQFHPHPEHUV
LQWKHHQFORVLQJFRQWH[W6LQFHQHVWHGWRSOHYHOFODVVHVDUHVWDWLFWKHLUPHWKRGVGR
QRWKDYHDQ\ RXWHU LQVWDQFHRIWKHHQFORVLQJFRQWH[W
)LJXUHLVDFODVVGLDJUDPWKDWLOOXVWUDWHVWRSOHYHOQHVWHGFODVVHVDQGLQWHUIDFHV
7KHVHDUHVKRZQDVPHPEHUVRIWKHHQFORVLQJFRQWH[WZLWKWKH^VWDWLF`WDJWRLQGLF
DWHWKDWWKH\DUHVWDWLFLHWKH\FDQEHLQVWDQWLDWHGZLWKRXWUHJDUGWRDQ\RXWHU
REMHFWRIWKHHQFORVLQJFRQWH[W6LQFHWKH\DUHPHPEHUVRIDFODVVRUDQLQWHUIDFH
WKHLUDFFHVVLELOLW\FDQEHVSHFLILHGH[DFWO\OLNHWKDWRIDQ\RWKHUPHPEHURIDFODVV
RULQWHUIDFH7KHFODVVHVIURPWKHGLDJUDPDUHLPSOHPHQWHGLQ([DPSOH

Figure 7.1 Top-level Nested Classes and Interfaces

Example 7.2 Access in Top-level Nested Classes and Interfaces


// Filename: AccessInTopLevelClass.java
public class AccessInTopLevelClass { // (1)
public void nonStaticMethod() { // (2)
System.out.println("nonstaticMethod in AccessInTopLevelClass");
}
private static class NestedTopLevelClass { // (3)
private static int i; // (4)
private int j; // (5)
public static void staticMethod() { // (6)
System.out.println("staticMethod in NestedTopLevelClass");
}
interface NestedTopLevelInterface1 { int Y2K = 2000; } // (7)
protected static class NestedTopLevelClass1
implements NestedTopLevelInterface1 { // (8)
private int k = Y2K; // (9)
SECTION 7.2: TOP-LEVEL NESTED CLASSES AND INTERFACES 229

public void anotherNonStaticMethod() { // (10)


// int jj = j; // (11) Not OK.
int ii = i; // (12)
int kk = k; // (13)
// nonStaticMethod(); // (14) Not OK.
staticMethod(); // (15)
}
public static void main (String args[]) {
int ii = i; // (16)
// int kk = k; // (17) Not OK.
staticMethod(); // (18)
}
}
}
}

2XWSXWIURPWKHSURJUDP
staticMethod in NestedTopLevelClass

([DPSOHGHPRQVWUDWHVDFFHVVLQJPHPEHUVGLUHFWO\LQWKHHQFORVLQJFRQWH[WRI
FODVVNestedTopLevelClass1GHILQHGDW  7KHLQLWLDOL]DWLRQDW  LVYDOLGVLQFHWKH
YDULDEOHY2KGHILQHGLQWKHRXWHULQWHUIDFHNestedTopLevelInterface1DW  LVLPSOLF
LWO\ VWDWLF 7KH FRPSLOHU ZLOO IODJ DQ HUURU DW   DQG   LQ PHWKRG another
NonStaticMethod() EHFDXVH GLUHFW DFFHVV WR QRQVWDWLF PHPEHUV LQ WKH HQFORVLQJ
FODVVLVQRWSHUPLWWHGE\DQ\PHWKRGLQDQHVWHGWRSOHYHOFODVV,WZLOODOVRIODJDQ
HUURUDW  LQPHWKRGmain()EHFDXVHDVWDWLFPHWKRGFDQQRWDFFHVVGLUHFWO\RWKHU
QRQVWDWLFYDULDEOHVLQLWVRZQFODVV6WDWHPHQWVDW  DQG  RQO\DFFHVVstatic
PHPEHUVLQWKHHQFORVLQJFRQWH[W7KHUHIHUHQFHVLQWKHVHVWDWHPHQWVFDQDOVREH
VSHFLILHGXVLQJIXOOQDPHV
int ii = AccessInTopLevelClass.NestedTopLevelClass.i;
AccessInTopLevelClass.NestedTopLevelClass.staticMethod();

1RWHWKDWDWRSOHYHOQHVWHGFODVVFDQGHILQHERWK staticDQGLQVWDQFHPHPEHUV
OLNHDQ\RWKHUSDFNDJHOHYHOFODVV+RZHYHULWVFRGHFDQRQO\GLUHFWO\DFFHVVstatic
PHPEHUVLQLWVHQFORVLQJFRQWH[W
$WRSOHYHOQHVWHGFODVVEHLQJDPHPEHURIWKHHQFORVLQJFODVVRULQWHUIDFHFDQ
KDYHDQ\DFFHVVLELOLW\ publicprotectedSDFNDJHGHIDXOWprivate OLNHDQ\RWKHU
PHPEHUVRIDFODVV7KHFODVV NestedTopLevelClassDW  KDV privateDFFHVVLELOLW\
ZKHUHDVLWVQHVWHGFODVVNestedTopLevelClass1DW  KDVprotectedDFFHVVLELOLW\7KH
FODVVNestedTopLevelClass1GHILQHVWKHPHWKRGmain()ZKLFKFDQEHH[HFXWHGE\WKH
FRPPDQG
java AccessInTopLevelClass$NestedTopLevelClass$NestedTopLevelClass1

1RWHWKDWWKHFODVVNestedTopLevelClass1LVVSHFLILHGXVLQJWKHIXOOQDPHRIWKHFODVV
ILOHPLQXVWKHH[WHQVLRQ
230 CHAPTER 7: INNER CLASSES

7.3 Non-static Inner Classes


1RQVWDWLFLQQHUFODVVHVDUHGHILQHGZLWKRXWWKHNH\ZRUGstaticDVPHPEHUVRIDQ
HQFORVLQJFODVVDQGFDQDOVREHQHVWHGWRDQ\GHSWK1RQVWDWLFLQQHUFODVVHVDUHRQ
SDUZLWKRWKHUQRQVWDWLFPHPEHUVGHILQHGLQDFODVV7KHIROORZLQJDVSHFWVDERXW
QRQVWDWLFLQQHUFODVVHVVKRXOGEHQRWHG
‡ $Q LQVWDQFH RI D QRQVWDWLF LQQHU FODVV FDQ RQO\ H[LVW ZLWK DQ LQVWDQFH RI LWV
HQFORVLQJFODVV7KLVPHDQVWKDWDQLQVWDQFHRIDQRQVWDWLFLQQHUFODVVPXVWEH
FUHDWHGLQWKHFRQWH[WRIDQLQVWDQFHRIWKHHQFORVLQJFODVV7KLVDOVRPHDQVWKDW
DQRQVWDWLFLQQHUFODVVFDQQRWKDYH staticPHPEHUV,QRWKHUZRUGVWKHFODVV
GRHVQRWSURYLGHDQ\VHUYLFHVRQO\LQVWDQFHVRIWKHFODVVGR
‡ 0HWKRGVRIDQRQVWDWLFLQQHUFODVVFDQGLUHFWO\UHIHUWRDQ\PHPEHU LQFOXGLQJ
FODVVHV  RI DQ\ HQFORVLQJ FODVV LQFOXGLQJ private PHPEHUV 1R H[SOLFLW UHIHU
HQFHLVUHTXLUHG
‡ 6LQFHDQRQVWDWLFLQQHUFODVVLVDPHPEHURIDQHQFORVLQJFODVVLWFDQKDYHDQ\
DFFHVVLELOLW\publicSDFNDJHGHIDXOWprotectedRUprivate

Example 7.3 Defining Non-static Inner Classes


class ToplevelClass { // (1)
private String msg = "Shine the inner light."; // (2)
public NonStaticInnerClass makeInstance() { // (3)
return new NonStaticInnerClass(); // (4)
}
public class NonStaticInnerClass { // (5)
// private static int staticVar; // (6) Not OK.
private String string; // (7)
public NonStaticInnerClass() { string = msg; } // (8)
public void printMsg() { System.out.println(string); } // (9)
}
}
public class Client { // (10)
public static void main(String args[]) { // (11)
ToplevelClass topRef = new ToplevelClass(); // (12)
ToplevelClass.NonStaticInnerClass innerRef1 =
topRef.makeInstance(); // (13)
innerRef1.printMsg(); // (14)
// ToplevelClass.NonStaticInnerClass innerRef2 =
// new ToplevelClass.NonStaticInnerClass(); // (15) Not OK.
ToplevelClass.NonStaticInnerClass innerRef3 =
topRef.new NonStaticInnerClass(); // (16)
}
}

2XWSXWIURPWKHSURJUDP
Shine the inner light.
SECTION 7.3: NON-STATIC INNER CLASSES 231

,Q([DPSOHWKHFODVVToplevelClassDW  GHILQHVDQRQVWDWLFLQQHUFODVVDW  
'HFODUDWLRQRIDVWDWLFYDULDEOHLQFODVV NonStaticInnerClassZRXOGEHIODJJHGDVD
FRPSLOHWLPHHUURUDVDQRQVWDWLFLQQHUFODVVFDQQRWGHILQHstaticPHPEHUV
7KH QRQVWDWLF PHWKRG makeInstance() DW   LQ WKH FODVV ToplevelClass FUHDWHV DQ
LQVWDQFH RI WKH NonStaticInnerClass XVLQJ WKH new RSHUDWRU DV VKRZQ DW   7KLV
FUHDWHVDQLQVWDQFHRIDQRQVWDWLFLQQHUFODVVLQWKHFRQWH[WRIWKHLQVWDQFHRIWKH
HQFORVLQJFODVVRQZKLFKWKHmakeInstance()PHWKRGLVLQYRNHG7KHmakeInstance()
PHWKRGLVFDOOHGDW  7KHUHIHUHQFHWRDQREMHFWRIWKHQRQVWDWLFLQQHUFODVVFDQ
WKHQEHXVHGLQWKHQRUPDOZD\WRDFFHVVLWVPHPEHUVDVVKRZQDW  $QDWWHPSW
WRFUHDWHDQLQVWDQFHRIWKHQRQVWDWLFLQQHUFODVVZLWKRXWDQRXWHULQVWDQFHXVLQJ
WKHnewRSHUDWRUZLWKWKHIXOOQDPHRIWKHLQQHUFODVVDVVKRZQDW  UHVXOWVLQD
FRPSLOHWLPHHUURU$VSHFLDOIRUPRIWKHnewRSHUDWRUPXVWEHXVHGZKLFKLVLOOXV
WUDWHGDW  
topRef.new NonStaticInnerClass(); // (16)

7KHH[SUHVVLRQHQFORVLQJREMHFWUHIHUHQFH!LQWKHV\QWD[
HQFORVLQJREMHFWUHIHUHQFH!.new
HYDOXDWHVWRDQLQVWDQFHRIWKHHQFORVLQJFODVVLQZKLFKWKHGHVLJQDWHGQRQVWDWLF
LQQHUFODVVLVGHILQHG,WLVDQHUURUWRVSHFLI\WKHIXOOQDPHRIWKHLQQHUFODVVDVWKH
HQFORVLQJ FRQWH[W LV DOUHDG\ JLYHQ E\ HQFORVLQJ REMHFW UHIHUHQFH! 7KH UHIHUHQFH
topRefGHQRWHVDQREMHFWRIFODVVToplevelClass$IWHUWKHH[HFXWLRQRIWKHVWDWHPHQW
DW   WKH ToplevelClass REMHFW KDV WZR LQVWDQFHV RI WKH LQQHU FODVV NonStatic
InnerClassDVVRFLDWHGZLWKLW7KLVLVGHSLFWHGLQ)LJXUHZKHUHWKHRXWHUREMHFW
GHQRWHGE\ topRef RIFODVV ToplevelClassLVVKRZQZLWKLWVWZRDVVRFLDWHGLQQHU
REMHFWV GHQRWHGE\innerRef1DQGinnerRef3UHVSHFWLYHO\ ULJKWDIWHUWKHH[HFXWLRQ
RIWKHVWDWHPHQWDW  ,QRWKHUZRUGVPXOWLSOHREMHFWVRIWKHLQQHUFODVVHVFDQEH
DVVRFLDWHGZLWKDQREMHFWRIDQHQFORVLQJFODVVDWUXQWLPH

topRef:ToplevelClass

innerRef1:NonStaticInnerClass

innerRef3:NonStaticInnerClass

Figure 7.2 Outer Object with Associated Inner Objects

$QLPSOLFLWUHIHUHQFHWRWKHHQFORVLQJREMHFWLVDOZD\VDYDLODEOHLQHYHU\PHWKRG
DQGFRQVWUXFWRURIDQRQVWDWLFLQQHUFODVV$PHWKRGFDQH[SOLFLWO\XVHWKLVUHIHU
HQFHZLWKDVSHFLDOIRUPRIWKHthisFRQVWUXFWDVH[SODLQHGEHORZ
)URPZLWKLQDQRQVWDWLFLQQHUFODVVLWLVSRVVLEOHWRUHIHUWRPHPEHUVLQWKHHQFORV
LQJFODVVGLUHFWO\$QH[DPSOHLVVKRZQDW  ZKHUHWKHLQVWDQFHYDULDEOHmsgIURP
WKH HQFORVLQJ FODVV LV DFFHVVHG LQ WKH QRQVWDWLF LQQHU FODVV ,W LV DOVR SRVVLEOH WR
232 CHAPTER 7: INNER CLASSES

H[SOLFLWO\UHIHUWRPHPEHUVLQWKHHQFORVLQJFODVVEXWWKLVUHTXLUHVVSHFLDOXVDJHRI
WKHthisUHIHUHQFH2QHPLJKWEHWHPSWHGWRGHILQHWKHFRQVWUXFWRUDW  DVIROORZV
public NonStaticInnerClass() { this.string = this.msg; }

7KHUHIHUHQFHthis.stringLVFRUUHFWEHFDXVHWKHLQVWDQFHYDULDEOHstringFHUWDLQO\
EHORQJVWRWKHFXUUHQWREMHFW GHQRWHGE\this RINonStaticInnerClassEXWthis.msg
FDQQRW SRVVLEO\ ZRUN DV WKH FXUUHQW REMHFW LQGLFDWHG E\ this  RI NonStaticInner
ClassKDVQRLQVWDQFHYDULDEOHmsg7KHFRUUHFWV\QWD[LVWKHIROORZLQJ

public NonStaticInnerClass() { this.string = ToplevelClass.this.msg; }

7KHH[SUHVVLRQ
HQFORVLQJFODVVQDPH!.this
HYDOXDWHVWRDUHIHUHQFHWKDWGHQRWHVWKHHQFORVLQJREMHFW RIFODVVHQFORVLQJFODVV
QDPH! RIWKHFXUUHQWLQVWDQFHRIDQRQVWDWLFLQQHUFODVV

Accessing Shadowed Members from Non-static Inner Classes


$VQRQVWDWLFLQQHUFODVVHVFDQEHQHVWHGQDPHVRILQVWDQFHPHPEHUVLQHQFORVLQJ
FODVVHVFDQEHFRPHVKDGRZHG7KHVSHFLDOIRUPRIWKH thisV\QWD[FDQEHXVHGWR
DFFHVVPHPEHUVLQWKHHQFORVLQJFRQWH[W

Example 7.4 Special Form of this and new Constructs in Non-static Inner Classes
// Filename: Client2.java
class TLClassA { // (1) Top-level Class
private String msg = "TLClassA object ";
public TLClassA(String objNo) { msg = msg + objNo; }
public void printMessage() { System.out.println(msg); }
class InnerB { // (2) Non-static Inner Class
private String msg = "InnerB object ";
public InnerB(String objNo) { msg = msg + objNo; }
public void printMessage() { System.out.println(msg); }
class InnerC { // (3) Non-static Inner Class
private String msg = "InnerC object ";
public InnerC(String objNo) { msg = msg + objNo; }
public void printMessage() {
System.out.println(msg); // (4)
System.out.println(this.msg); // (5)
System.out.println(InnerC.this.msg); // (6)
System.out.println(InnerB.this.msg); // (7)
InnerB.this.printMessage(); // (8)
System.out.println(TLClassA.this.msg); // (9)
TLClassA.this.printMessage(); // (10)
}
}
}
}
SECTION 7.3: NON-STATIC INNER CLASSES 233

public class Client2 { // (11)


public static void main(String args[]) { // (12)
TLClassA a = new TLClassA("1"); // (13)
TLClassA.InnerB b = a.new InnerB("1"); // (14)
TLClassA.InnerB.InnerC c = b.new InnerC("1"); // (15)
c.printMessage(); // (16)
TLClassA.InnerB bb = new TLClassA("2").new InnerB("2");// (17)
TLClassA.InnerB.InnerC cc = bb.new InnerC("2"); // (18)
cc.printMessage(); // (19)
TLClassA.InnerB.InnerC ccc =
new TLClassA("3").new InnerB("3").new InnerC("3"); // (20)
}
}

2XWSXWIURPWKHSURJUDP
InnerC object 1
InnerC object 1
InnerC object 1
InnerB object 1
InnerB object 1
TLClassA object 1
TLClassA object 1
InnerC object 2
InnerC object 2
InnerC object 2
InnerB object 2
InnerB object 2
TLClassA object 2
TLClassA object 2

([DPSOHLOOXVWUDWHVWKHVSHFLDOIRUPRIWKHthisFRQVWUXFWWRDFFHVVPHPEHUVLQ
WKHHQFORVLQJFRQWH[WDQGDOVRGHPRQVWUDWHVWKHVSHFLDOIRUPRIWKHnewFRQVWUXFW
WRFUHDWHLQVWDQFHVRIQRQVWDWLFLQQHUFODVVHV7KHH[DPSOHVKRZVWKHFODVVInnerC
GHILQHGDW  ZKLFKLVQHVWHGLQWKHFODVV InnerBGHILQHGDW  ZKLFKLQWXUQLV
QHVWHGLQWKHWRSOHYHOFODVV TLClassADW  $OOWKUHHFODVVHVKDYHD privateQRQ
VWDWLF StringYDULDEOH msgDQGDQRQVWDWLFPHWKRG printMessage()7KHVHPHPEHUV
DUHQRWRYHUULGGHQLQWKHLQQHUFODVVHVDVQRLQKHULWDQFHLVLQYROYHG/LNHDQ\RWKHU
FODVVPHPEHUWKH\KDYHFODVVVFRSH
7KH main()PHWKRGDW  XVHVWKHDGGLWLRQDOV\QWD[RIWKH newRSHUDWRUWRFUHDWH
DQLQVWDQFHRI InnerC GHQRWHGE\ c DW  LQWKHFRQWH[WRIDQLQVWDQFHRIFODVV
InnerB GHQRWHGE\b DW  ZKLFKLQWXUQLVFUHDWHGLQWKHFRQWH[WRIDQLQVWDQFH
RIFODVVTLClassA GHQRWHGE\a DW  
7KH UHIHUHQFH c LV XVHG DW   WR LQYRNH WKH PHWKRG printMessage() IURP FODVV
InnerC 7KLV PHWKRG XVHV WKH VWDQGDUG this UHIHUHQFH WR DFFHVV PHPEHUV RI WKH
REMHFWRQZKLFKLWLVLQYRNHGDVVKRZQDW  ,WDOVRXVHVWKHVSHFLDOIRUPRIWKH
thisFRQVWUXFWLQFRQMXQFWLRQZLWKWKHFODVVQDPHWRDFFHVVPHPEHUVLQ RXWHU
REMHFWVZKLFKDUHDVVRFLDWHGZLWKWKHFXUUHQWREMHFWDVVKRZQLQWKHVWDWHPHQWV
IURP  WKURXJK  
234 CHAPTER 7: INNER CLASSES

:KHQWKHLQWHUYHQLQJUHIHUHQFHVWRDQRQVWDWLFLQQHUFODVVDUHRIQRLQWHUHVWWKH
newRSHUDWRUFDQEHFKDLQHGDVVKRZQDW    DQG  

1RWHWKDWWKH RXWHU REMHFWVDVVRFLDWHGZLWKWKHUHIHUHQFHVcccDQGcccDUHGLVWLQFW


DVHYLGHQWIURPWKHSURJUDPRXWSXW

Compiling and Importing Non-static Inner Classes


,IWKHILOHClient2.javaFRQWDLQLQJWKHGHILQLWLRQVIURP([DPSOHLVFRPSLOHGLW
ZLOOUHVXOWLQWKHJHQHUDWLRQRIWKHIROORZLQJFODVVILOHVZKHUHHDFKILOHFRUUHVSRQGV
WRDFODVVGHILQLWLRQ
TLClassA$InnerB$InnerC.class
TLClassA$InnerB.class
TLClassA.class
Client2.class

&OLHQWVFDQXVHWKH importVWDWHPHQWWRSURYLGHDVKRUWFXWIRUWKHQDPHVRIQRQ
VWDWLFLQQHUFODVVHV([DPSOHEDVHGRQ([DPSOHVKRZVKRZQHVWHGFODVVHV
FDQEHLPSRUWHGDQGXVHG1RWHWKHVSHFLILFDWLRQRIWKHFODVVQDPHLQWKH import
VWDWHPHQW,W´LPSRUWVµWKHLPPHGLDWHQHVWHGFODVVHVDVVKRZQDW · )RUGHHSO\
QHVWHGLQQHUFODVVHVWKHLQWHUYHQLQJFODVVQDPHVPXVWEHVSHFLILHGDVVKRZQLQWKH
GHFODUDWLRQVDW ·  · DQG · ,IWKHFODVVTLClassAEHORQJHGWRDQDPHGSDFN
DJHWKHQWKHSDFNDJHQDPHPXVWEHSUHSHQGHGWRWKHFODVV·VQDPHLQWKHXVXDO
ZD\LQWKHimportVWDWHPHQW

Example 7.5 Importing Inner Classes


// Filename: Client3.java
import TLClassA.*;
// Uses classes from Example 7.4.

public class Client3 {


public static void main(String args[]) { // (12)
TLClassA a = new TLClassA("1"); // (13)
InnerB b = a.new InnerB("1"); // (14')
InnerB.InnerC c = b.new InnerC("1"); // (15')
InnerB bb = new TLClassA("2").new InnerB("2"); // (17')
InnerB.InnerC cc = bb.new InnerC("2"); // (18')
InnerB.InnerC ccc =
new TLClassA("3").new InnerB("3").new InnerC("3"); // (20')
ccc.printMessage();
}
}

2XWSXWIURPWKHSURJUDP
InnerC object 3
InnerC object 3
InnerC object 3
InnerB object 3
SECTION 7.3: NON-STATIC INNER CLASSES 235

InnerB object 3
TLClassA object 3
TLClassA object 3

Inheritance and Containment Hierarchy of Non-static Inner


Classes
1RQVWDWLFLQQHUFODVVHVFDQH[WHQGRWKHUFODVVHVDQGFDQWKHPVHOYHVEHH[WHQGHG
7KHUHIRUH ERWK WKH LQKHULWDQFH DQG FRQWDLQPHQW KLHUDUFK\ PXVW EH FRQVLGHUHG
ZKHQGHDOLQJZLWKPHPEHUDFFHVV,PDJLQHDVXEFODVVCWKDWLVGHULYHGIURPVXSHU
FODVV B DQG FODVV C LV DOVR D QRQVWDWLF LQQHU FODVV LQ DQ HQFORVLQJ FODVV A ,Q WKH
DEVHQFHRIQDPHFRQIOLFWVWKHUHLVQRSUREOHPEXWZKDWLIERWKWKHVXSHUFODVVBDQG
WKHHQFORVLQJFODVVAKDGDPHPEHUZLWKWKHQDPHx",IDQDPHFRQIOLFWDULVHVWKH
LQKHULWHGPHPEHUVKDGRZVWKHPHPEHUZLWKWKHVDPHQDPHLQWKHHQFORVLQJFODVV
7KHFRPSLOHUKRZHYHUUHTXLUHVWKDWH[SOLFLWUHIHUHQFHVEHXVHG
,Q([DPSOHWKHFRPSLOHUZRXOGIODJDQHUURUDW  DVWKHUHIHUHQFHxLVDPELJX
RXV7KHVWDQGDUGIRUPRIWKH thisUHIHUHQFHFDQEHXVHGWRDFFHVVWKHLQKHULWHG
PHPEHU DV VKRZQ DW   7KH NH\ZRUG super ZRXOG EH DQRWKHU DOWHUQDWLYH 7R
DFFHVVWKHPHPEHUIURPWKHHQFORVLQJFRQWH[WWKHVSHFLDOIRUPRIWKH thisUHIHU
HQFHWRJHWKHUZLWKWKHHQFORVLQJFODVVQDPHLVXVHGDVVKRZQDW  

Example 7.6 Inheritance and Containment Hierarchy


class B {
protected double x = 2.17;
}
class A { // (1) Top-level Class
private double x = 3.14;

class C extends B { // (2) Non-static inner Class


// private double w = x; // (3) Compile time error
private double y = this.x; // (4) x from superclass
private double z = A.this.x; // (5) x from enclosing class
public void printX() { // (6)
System.out.println("this.x: " + y);
System.out.println("A.this.x: " + z);
}
}
}
public class Client4 { // (7)
public static void main(String args[]) {
A.C ref = new A().new C();
ref.printX();
}
}
236 CHAPTER 7: INNER CLASSES

2XWSXWIURPWKHSURJUDP
this.x: 2.17
A.this.x: 3.14

Review questions

 :KDWZLOOEHWKHUHVXOWRIDWWHPSWLQJWRFRPSLOHDQGUXQWKHIROORZLQJFRGH"
public class MyClass {
public static void main(String args[]) {
Outer objRef = new Outer();
System.out.println(objRef.createInner().getSecret());
}
}
class Outer {
private int secret;
Outer() { secret = 123; }
class Inner {
int getSecret() { return secret; }
}
Inner createInner() { return new Inner(); }
}

6HOHFWWKHRQHULJKWDQVZHU
D 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKHFODVV InnerFDQQRWEHGHFODUHGZLWKLQ
WKHFODVVOuter
E 7KH FRGH ZLOO IDLO WR FRPSLOH VLQFH WKH PHWKRG createInner() FDQQRW EH
DOORZHGWRSDVVREMHFWVRIWKHLQQHUFODVVInnerWRPHWKRGVRXWVLGHRIWKHFODVV
Outer
F 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKH secretYDULDEOHLVQRWDFFHVVLEOHIURP
WKHPHWKRGgetSecret()
G 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKHPHWKRGgetSecret()LVQRWYLVLEOHIURP
WKHmain()PHWKRGLQWKHFODVVMyClass
H 7KHFRGHZLOOFRPSLOHZLWKRXWHUURUDQGZLOOSULQW123ZKHQUXQ

 :KLFKRIWKHVHVWDWHPHQWVFRQFHUQLQJQHVWHGFODVVHVDUHWUXH"
6HOHFWDOOYDOLGDQVZHUV
D $QLQVWDQFHRIDWRSOHYHOQHVWHGFODVVKDVDQLQKHUHQWRXWHULQVWDQFH
E $WRSOHYHOQHVWHGFODVVFDQFRQWDLQQRQVWDWLFPHPEHUYDULDEOHV
F $WRSOHYHOQHVWHGLQWHUIDFHFDQFRQWDLQQRQVWDWLFPHPEHUYDULDEOHV
G $WRSOHYHOQHVWHGLQWHUIDFHKDVDQLQKHUHQWRXWHULQVWDQFH
H )RUHDFKLQVWDQFHRIWKHRXWHUFODVVWKHUHFDQH[LVWPDQ\LQVWDQFHVRIDQRQ
VWDWLFLQQHUFODVV
SECTION 7.3: NON-STATIC INNER CLASSES 237

 :KDWZLOOEHWKHUHVXOWRIDWWHPSWLQJWRFRPSLOHDQGUXQWKHIROORZLQJFRGH"
public class MyClass {
public static void main(String args[]) {
State st = new State();
System.out.println(st.getValue());
State.Memento mem = st.memento();
st.alterValue();
System.out.println(st.getValue());
mem.restore();
System.out.println(st.getValue());
}
public static class State {
protected int val = 11;
int getValue() { return val; }
void alterValue() { val = (val + 7) % 31; }
Memento memento() { return new Memento(); }
class Memento {
int val;
Memento() { this.val = State.this.val; }
void restore() { ((State) this).val = this.val; }
}
}
}

6HOHFWWKHRQHULJKWDQVZHU
D 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKHVWDWLF main()PHWKRGWULHVWRFUHDWHD
QHZLQVWDQFHRIWKHLQQHUFODVVState
E 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKHFODVVGHFODUDWLRQRIState.Memento LVQRW
YLVLEOHIURPWKHmain()PHWKRG
F 7KHFRGHZLOOIDLOWRFRPSLOHVLQFHWKHLQQHUFODVV MementoGHFODUHVDYDULDEOH
ZLWKWKHVDPHQDPHDVDYDULDEOHLQWKHRXWHUFODVVState
G 7KH FRGH ZLOO IDLO WR FRPSLOH VLQFH WKH Memento FRQVWUXFWRU WULHV DQ LQYDOLG
DFFHVVWKURXJKWKHState.this.valH[SUHVVLRQ
H 7KH FRGH ZLOO IDLO WR FRPSLOH VLQFH WKH Memento PHWKRG restore() WULHV DQ
LQYDOLGDFFHVVWKURXJKWKH((State) this).valH[SUHVVLRQ
I 7KHSURJUDPFRPSLOHVZLWKRXWHUURUVDQGSULQWV1118DQG11ZKHQUXQ

 :KDWZLOOEHWKHUHVXOWRIDWWHPSWLQJWRFRPSLOHDQGUXQWKHIROORZLQJSURJUDP"
public class Nesting {
public static void main(String args[]) {
B.C obj = new B().new C();
}
}
class A {
int val;
A(int v) { val = v; }
}
238 CHAPTER 7: INNER CLASSES

class B extends A {
int val = 1;
B() { super(2); }
class C extends A {
int val = 3;
C() {
super(4);
System.out.println(B.this.val);
System.out.println(C.this.val);
System.out.println(super.val);
}
}
}

6HOHFWDOOYDOLGDQVZHUV
D 7KHSURJUDPZLOOIDLOWRFRPSLOH
E 7KH SURJUDP ZLOO FRPSLOH ZLWKRXW HUURU DQG SULQW 2 3 DQG 4 LQ WKDW RUGHU
ZKHQUXQ
F 7KH SURJUDP ZLOO FRPSLOH ZLWKRXW HUURU DQG SULQW 1 4 DQG 2 LQ WKDW RUGHU
ZKHQUXQ
G 7KH SURJUDP ZLOO FRPSLOH ZLWKRXW HUURU DQG SULQW 1 3 DQG 4 LQ WKDW RUGHU
ZKHQUXQ
H 7KH SURJUDP ZLOO FRPSLOH ZLWKRXW HUURU DQG SULQW 3 2 DQG 1 LQ WKDW RUGHU
ZKHQUXQ

7.4 Local Classes


$ORFDOFODVVLVDFODVVWKDWLVGHILQHGLQDEORFN7KLVFRXOGEHDPHWKRGERG\DFRQ
VWUXFWRUDORFDOEORFNDstaticLQLWLDOL]HURUDQLQVWDQFHLQLWLDOL]HU6XFKDORFDOFODVV
LVRQO\YLVLEOHZLWKLQWKHFRQWH[WRIWKHEORFNLHWKHQDPHRIWKHFODVVLVRQO\YDOLG
LQWKHFRQWH[WRIWKHEORFNLQZKLFKLWLVGHILQHG$ORFDOFODVVFDQQRWEHVSHFLILHG
ZLWKWKHNH\ZRUGstatic+RZHYHULIWKHFRQWH[WLVVWDWLF LHDVWDWLFPHWKRGRUD
VWDWLFLQLWLDOL]HU WKHQWKHORFDOFODVVLVLPSOLFLWO\VWDWLF2WKHUZLVHWKHORFDOFODVVLV
QRQVWDWLF
/LNH QRQVWDWLF LQQHU FODVVHV DQ LQVWDQFH RI D QRQVWDWLF ORFDO FODVV LV SDVVHG D
KLGGHQUHIHUHQFHGHVLJQDWLQJDQLQVWDQFHRILWVHQFORVLQJFODVVLQLWVFRQVWUXFWRUV
DQG WKLV JLYHV QRQVWDWLF ORFDO FODVVHV PXFK RI WKH VDPH FDSDELOLW\ DV QRQVWDWLF
LQQHUFODVVHV6RPHUHVWULFWLRQVZKLFKDSSO\WRORFDOFODVVHVDUH
‡ /RFDO FODVVHV FDQQRW KDYH static PHPEHUV DV WKH\ FDQQRW SURYLGH FODVV
VSHFLILFVHUYLFHV
‡ /RFDOFODVVHVFDQQRWKDYHDQ\DFFHVVLELOLW\7KLVUHVWULFWLRQDSSOLHVWRORFDOYDUL
DEOHVDQGLVDOVRHQIRUFHGIRUORFDOFODVVHV
SECTION 7.4: LOCAL CLASSES 239

Example 7.7 Access in Local Classes


class SuperB {
protected double x;
protected static int n;
}
class SuperC {
protected double y;
protected static int m;
}
class TopLevelA extends SuperC { // Top-level Class
private double z;
private static int p;
void nonStaticMethod(final int i) { // Non-static Method
final int j = 10;
int k;
class NonStaticLocalD extends SuperB { // Non-static local class
// static double d; // (1) Not OK. Only non-static members allowed.
int ii = i; // (2) final from enclosing method.
int jj = j; // (3) final from enclosing method.
// double kk = k; // (4) Not OK. Only finals from enclosing method.
double zz = z; // (5) non-static from enclosing class.
int pp = p; // (6) static from enclosing class.
double yy = y; // (7) inherited by enclosing class.
int mm = m; // (8) static from enclosing class.
double xx = x; // (9) non-static inherited from superclass
int nn = n; // (10) static from superclass
}
}
static void staticMethod(final int i) { // Static Method
final int j = 10;
int k;
class StaticLocalE extends SuperB { // Static local class
// static double d; // (11) Not OK. Only non-static members allowed.
int ii = i; // (12) final from enclosing method.
int jj = j; // (13) final from enclosing method.
// double kk = k; // (14) Not OK. Non-final from enclosing method.
// double zz = z; // (15) Not OK. Non-static member.
int pp = p; // (16) static from enclosing class.
// double yy = y; // (17) Not OK. Non-static member.
int mm = m; // (18) static from enclosing class.
double xx = x; // (19) non-static inherited from superclass
int nn = n; // (20) static from superclass
}
}
}
240 CHAPTER 7: INNER CLASSES

Access Rules for Local Classes


([DPSOHLOOXVWUDWHVWKHDFFHVVUXOHVIRUORFDOFODVVHVZKLFKDUHVWDWHGEHORZ
‡ $ ORFDO FODVV FDQ DFFHVV PHPEHUV GHILQHG ZLWKLQ WKH FODVV 7KLV VKRXOG QRW
FRPHDVDVXUSULVH
‡ $ ORFDO FODVV FDQ DFFHVV final ORFDO YDULDEOHV final PHWKRG SDUDPHWHUV DQG
final catchEORFNSDUDPHWHUVLQWKHVFRSHRIWKHORFDOFRQWH[W6XFK finalYDUL
DEOHVDUHDOVRUHDGRQO\LQWKHORFDOFODVV7KLVVLWXDWLRQLVVKRZQDW  DQG  
ZKHUH WKH final SDUDPHWHU i DQG WKH final ORFDO YDULDEOH j RI WKH PHWKRG
nonStaticMethod()LQWKHQRQVWDWLFORFDOFODVVNonStaticLocalDDUHDFFHVVHG7KLV
DOVRDSSOLHVWRVWDWLFORFDOFODVVHVDVVKRZQDW  DQG  $FFHVVWRQRQILQDO
ORFDOYDULDEOHVLVQRWSHUPLWWHGIURPORFDOFODVVHVDVVKRZQDW  DQG  
‡ $QRQVWDWLFORFDOFODVVFDQDFFHVVPHPEHUVGHILQHGLQWKHHQFORVLQJFODVV7KLV
VLWXDWLRQLVVKRZQDW  DQG  ZKHUHWKHLQVWDQFHYDULDEOH zDQGVWDWLFYDUL
DEOH p GHILQHG LQ WKH HQFORVLQJ FODVV TopLevelA DUH DFFHVVHG UHVSHFWLYHO\ 7KH
VSHFLDO IRUP RI WKH this FRQVWUXFW FDQ EH XVHG IRU H[SOLFLW UHIHUHQFLQJ RI
PHPEHUVGHILQHGLQWKHHQFORVLQJFODVV
double zz = TopLevelA.this.z;
+RZHYHUDVWDWLFORFDOFODVVFDQRQO\GLUHFWO\DFFHVVstaticPHPEHUVGHILQHGLQ
WKHHQFORVLQJFODVVDVVKRZQDW  EXWQRWQRQVWDWLFPHPEHUVDVVKRZQDW
 
‡ $QRQVWDWLFORFDOFODVVFDQGLUHFWO\DFFHVVPHPEHUVLQKHULWHGE\WKHHQFORVLQJ
FODVV7KLVVLWXDWLRQLVVKRZQDW  DQG  ZKHUHWKHLQVWDQFHYDULDEOH yDQG
WKH VWDWLF YDULDEOH m DUH LQKHULWHG E\ WKH HQFORVLQJ FODVV TopLevelA IURP WKH
VXSHUFODVVSuperC7KHVSHFLDOIRUPRIWKHthisFRQVWUXFWFDQDOVREHXVHGLQWKH
ORFDOFODVVIRUH[SOLFLWUHIHUHQFLQJRIPHPEHUVLQKHULWHGE\WKHHQFORVLQJFODVV
double yy = TopLevelA.this.y;
+RZHYHUDVWDWLFORFDOFODVVFDQRQO\GLUHFWO\DFFHVV staticPHPEHUVWKDWDUH
LQKHULWHGE\WKHHQFORVLQJFODVVDVVKRZQDW  EXWQRWQRQVWDWLFPHPEHUV
DVVKRZQDW  
‡ $ORFDOFODVVFDQDFFHVVPHPEHUVLQKHULWHGIURPLWVVXSHUFODVVLQWKHXVXDOZD\
7KHLQVWDQFHYDULDEOHVxDQGnLQWKHVXSHUFODVVSuperBDUHLQKHULWHGE\WKHORFDO
VXEFODVV NonStaticLocalD 7KHVH YDULDEOHV DUH DFFHVVHG LQ WKH ORFDO FODVV Non
StaticLocalDDVVKRZQDW  DQG  7KHVWDQGDUGthisUHIHUHQFH RUWKHsuper
NH\ZRUG FDQEHXVHGIRUUHIHUHQFLQJPHPEHUVLQKHULWHGE\WKHORFDOFODVV
double xx = this.x;
1RWHWKDWWKLVDOVRDSSOLHVIRUVWDWLFORFDOFODVVHV7KLVLVVKRZQDW  DQG  

Instantiating Local Classes


&OLHQWV RXWVLGH WKH FRQWH[W RI D ORFDO FODVV FDQQRW FUHDWH RU DFFHVV WKHVH FODVVHV
GLUHFWO\EHFDXVHWKH\DUHDIWHUDOOORFDO$ORFDOFODVVFDQEHLQVWDQWLDWHGLQWKHEORFN
SECTION 7.4: LOCAL CLASSES 241

LQZKLFKLWLVGHILQHG$PHWKRGFDQUHWXUQDQLQVWDQFHRIWKHORFDOFODVV7KHORFDO
FODVVW\SHPXVWWKHQEHDVVLJQDEOHWRWKHUHWXUQW\SHRIWKHPHWKRG,WFDQQRWEH
WKH VDPH DV WKH ORFDO FODVV W\SH VLQFH WKLV W\SH LV QRW DFFHVVLEOH RXWVLGH RI WKH
PHWKRG2IWHQDVXSHUW\SHRIWKHORFDOFODVVLVVSHFLILHGDVWKHUHWXUQW\SH

Example 7.8 Instantiating Local Classes


interface IDrawable { // (1)
void draw();
}
class Shape implements IDrawable { // (2)
public void draw() { System.out.println("Drawing a Shape."); }
}
class Painter { // (3) Top-level Class
public Shape createCircle(final double radius) { // (4) Non-static Method
class Circle extends Shape { // (5) Non-static local class
public void draw() {
System.out.println("Drawing a Circle of radius: " + radius);
}
}
return new Circle(); // (6) Object of non-static local class
}
public static IDrawable createMap() { // (7) Static Method
class Map implements IDrawable { // (8) Static local class
public void draw() { System.out.println("Drawing a Map."); }
}
return new Map(); // (9) Object of static local class
}
}

public class Client {


public static void main(String args[]) {
IDrawable[] drawables = { // (10)
new Painter().createCircle(5),// (11) Object of non-static local class
Painter.createMap(), // (12) Object of static local class
new Painter().createMap() // (13) Object of static local class
};
for (int i = 0; i < drawables.length; i++) // (14)
drawables[i].draw();
System.out.println("Local Class Names:");
System.out.println(drawables[0].getClass()); // (15)
System.out.println(drawables[1].getClass()); // (16)
}
}

2XWSXWIURPWKHSURJUDP
Drawing a Circle of radius: 5.0
Drawing a Map.
Drawing a Map.
242 CHAPTER 7: INNER CLASSES

Local Class Names:


class Painter$1$Circle
class Painter$1$Map

([DPSOHLOOXVWUDWHVKRZFOLHQWVFDQLQVWDQWLDWHORFDOFODVVHV7KHQRQVWDWLFORFDO
FODVV CircleDW  LVGHILQHGLQWKHQRQVWDWLFPHWKRG createCircle()DW  ZKLFK
KDV WKH UHWXUQ W\SH Shape 7KH VWDWLF ORFDO FODVV Map DW   LV GHILQHG LQ WKH VWDWLF
PHWKRG createMap() DW   ZKLFK KDV WKH UHWXUQ W\SH IDrawable 7KH LQKHULWDQFH
KLHUDUFK\RIWKHORFDOFODVVHVDQGWKHLUVXSHUW\SHVShapeDQGIDrawableLVGHSLFWHG
LQ )LJXUH  7KH main() PHWKRG FUHDWHV D SRO\PRUSKLF DUUD\ drawables RI W\SH
IDrawableDW  ZKLFKLVLQLWLDOL]HGZLWKLQVWDQFHVRIWKHORFDOFODVVHV
IDrawable[] drawables = { // (10)
new Painter().createCircle(5), // (11) Object of non-static local class
Painter.createMap(), // (12) Object of static local class
new Painter().createMap() // (13) Object of static local class
};

&UHDWLQJDQLQVWDQFHRIDQRQVWDWLFORFDOFODVVUHTXLUHVDQLQVWDQFHRIWKHHQFORVLQJ
FODVV 7KH QRQVWDWLF PHWKRG createCircle() LV LQYRNHG RQ WKH LQVWDQFH RI WKH
HQFORVLQJFODVVWRFUHDWHDQLQVWDQFHRIWKHQRQVWDWLFORFDOFODVVDVVKRZQDW  
,QWKHQRQVWDWLFPHWKRGWKHUHIHUHQFHWRWKHLQVWDQFHRIWKHHQFORVLQJFRQWH[WLV
SDVVHGLPSOLFLWO\LQWKHFRQVWUXFWRUFDOORIWKHQRQVWDWLFORFDOFODVVDW  
$ VWDWLF PHWKRG FDQ EH LQYRNHG HLWKHU WKURXJK WKH FODVV QDPH RU WKURXJK DQ
LQVWDQFHRIWKHFODVV$QLQVWDQFHRIDVWDWLFORFDOFODVVFDQEHFUHDWHGLQHLWKHUZD\
E\FDOOLQJWKHcreateMap()PHWKRGDVVKRZQDW  DQG  $VPLJKWEHH[SHFWHG
QRRXWHUREMHFWLVLQYROYHG
$VUHIHUHQFHVWRDORFDOFODVVFDQQRWEHGHFODUHGRXWVLGHRIWKHORFDOFRQWH[WWKH
IXQFWLRQDOLW\ RI WKH FODVV LV RQO\ DYDLODEOH WKURXJK VXSHUW\SH UHIHUHQFHV 7KH
PHWKRGdraw()LVLQYRNHGRQREMHFWVLQWKHDUUD\DW  7KHSURJUDPRXWSXWLQGLF
DWHVZKLFKREMHFWVZHUHFUHDWHG,QSDUWLFXODUQRWHWKDWWKHfinalSDUDPHWHUradius
RIWKHPHWKRG createCircle()DW  LVDFFHVVHGE\WKH draw()PHWKRGRIWKHORFDO
FODVVCircleDW  $QLQVWDQFHRIWKHORFDOFODVVCircleLVFUHDWHGDW  E\DFDOOWR
WKHPHWKRG createCircle()7KH draw()PHWKRGLVLQYRNHGRQWKLVLQVWDQFHRIWKH
ORFDOFODVVCircleLQWKHORRSDW  7KHYDOXHRIWKHfinalSDUDPHWHUradiusLVVWLOO
DFFHVVLEOHWRWKH draw()PHWKRGLQYRNHGRQWKLVLQVWDQFHDOWKRXJKWKHFDOOWRWKH
PHWKRG createCircle() ZKLFK FUHDWHG WKH LQVWDQFH LQ WKH ILUVW SODFH KDV FRP
SOHWHG9DOXHVRIfinalORFDOYDULDEOHVFRQWLQXHWREHDYDLODEOHWRLQVWDQFHVRIORFDO
FODVVHVZKHQHYHUWKHVHYDOXHVDUHQHHGHG
7KHRXWSXWDOVRVKRZVWKHDFWXDOQDPHVRIWKHORFDOFODVVHV,QIDFWWKHORFDOFODVV
QDPHVDUHUHIOHFWHGLQWKHFODVVILOHQDPHV
SECTION 7.5: ANONYMOUS CLASSES 243

7.5 Anonymous Classes


&ODVVHV DUH XVXDOO\ ILUVW GHILQHG DQG WKHQ LQVWDQWLDWHG XVLQJ WKH new RSHUDWRU
$QRQ\PRXV FODVVHV FRPELQH WKH SURFHVV RI GHILQLWLRQ DQG LQVWDQWLDWLRQ LQWR D
VLQJOHVWHS$QRQ\PRXVFODVVHVDUHGHILQHGDWWKHORFDWLRQWKH\DUHLQVWDQWLDWHG
XVLQJDGGLWLRQDOV\QWD[ZLWKWKHnewRSHUDWRU$VWKHVHFODVVHVGRQRWKDYHDQDPH
DQLQVWDQFHRIWKHFODVVFDQRQO\EHFUHDWHGWRJHWKHUZLWKWKHGHILQLWLRQ
$QDQRQ\PRXVFODVVFDQEHGHILQHGDQGLQVWDQWLDWHGLQFRQWH[WVZKHUHDUHIHUHQFH
FDQ EH XVHG LH DV H[SUHVVLRQV WKDW HYDOXDWH WR D UHIHUHQFH GHQRWLQJ DQ REMHFW
$QRQ\PRXVFODVVHVDUHW\SLFDOO\XVHGIRUFUHDWLQJREMHFWV´RQWKHIO\µLQFRQWH[WV
VXFKDVWKHUHWXUQYDOXHRIDPHWKRGRUDVDQDUJXPHQWLQDPHWKRGFDOORULQ
LQLWLDOL]DWLRQRIYDULDEOHV$QRQ\PRXVFODVVHVFDQDOVREHXVHGWRH[WHQGDGDSWHU
FODVVHV 6HFWLRQS  
7KHFRQWH[WGHWHUPLQHVZKHWKHUWKHDQRQ\PRXVFODVVLVVWDWLFDQGWKHNH\ZRUG
staticLVQRWXVHGH[SOLFLWO\)RUH[DPSOHDQDQRQ\PRXVFODVVDVWKHUHWXUQYDOXH
RIDVWDWLFPHWKRGZRXOGEHVWDWLFDVLWZRXOGEHLILWZDVXVHGWRLQLWLDOL]HDVWDWLF
PHPEHUYDULDEOH

Extending an Existing Class


7KH IROORZLQJ V\QWD[ FDQ EH XVHG IRU GHILQLQJ DQG LQVWDQWLDWLQJ DQ DQRQ\PRXV
FODVVWKDWH[WHQGVDQH[LVWLQJFODVVVSHFLILHGE\VXSHUFODVVQDPH!
new VXSHUFODVVQDPH! (RSWLRQDODUJXPHQWOLVW!) { FODVVGHFODUDWLRQV! }
2SWLRQDO DUJXPHQWV FDQ EH VSHFLILHG ZKLFK DUH SDVVHG WR WKH VXSHUFODVV FRQ
VWUXFWRU 7KXV WKH VXSHUFODVV PXVW SURYLGH D FRQVWUXFWRU FRUUHVSRQGLQJ WR WKH
DUJXPHQWVSDVVHG6LQFHDQDQRQ\PRXVFODVVFDQQRWGHILQHFRQVWUXFWRUV DVLWGRHV
QRWKDYHDQDPH DQLQVWDQFHLQLWLDOL]HUFDQEHXVHGWRDFKLHYHWKHVDPHHIIHFWDV
DFRQVWUXFWRU1RextendsFODXVHLVXVHGLQWKHFRQVWUXFW

Example 7.9 Defining Anonymous Classes


interface IDrawable { // (1)
void draw();
}
class Shape implements IDrawable { // (2)
public void draw() { System.out.println("Drawing a Shape."); }
}
class Painter { // (3) Top-level Class
public Shape createShape() { // (4) Non-static Method
return new Shape(){ // (5) Extends superclass
public void draw() { System.out.println("Drawing a new Shape."); }
};
}
244 CHAPTER 7: INNER CLASSES

public static IDrawable createIDrawable() { // (7) Static Method


return new IDrawable(){ // (8) Implements interface
public void draw() {
System.out.println("Drawing a new IDrawable.");
}
};
}
}
public class Client {
public static void main(String args[]) { // (9)
IDrawable[] drawables = { // (10)
new Painter().createShape(), // (11) non-static anonymous class
Painter.createIDrawable(), // (12) static anonymous class
new Painter().createIDrawable() // (13) static anonymous class
};
for (int i = 0; i < drawables.length; i++) // (14)
drawables[i].draw();
System.out.println("Anonymous Class Names:");
System.out.println(drawables[0].getClass()); // (15)
System.out.println(drawables[1].getClass()); // (16)
}
}

2XWSXWIURPWKHSURJUDP
Drawing a new Shape.
Drawing a new IDrawable.
Drawing a new IDrawable.
Anonymous Class Names:
class Painter$1
class Painter$2

&ODVV GHILQLWLRQV IURP ([DPSOH  ZKLFK LV DQ DGDSWDWLRQ RI ([DPSOH  WR
DQRQ\PRXV FODVVHV DUH VKRZQ EHORZ 7KH LQVWDQFH PHWKRG createShape() DW 
GHILQHVDQRQVWDWLFDQRQ\PRXVFODVVDW  ZKLFKH[WHQGVWKHVXSHUFODVV Shape
7KHDQRQ\PRXVFODVVRYHUULGHVWKHLQKHULWHGPHWKRG draw()$VUHIHUHQFHVWRDQ
DQRQ\PRXVFODVVFDQQRWEHGHFODUHGWKHIXQFWLRQDOLW\RIWKHFODVVLVRQO\DYDLODEOH
WKURXJKVXSHUFODVVUHIHUHQFHV8VXDOO\LWPDNHVVHQVHWRHLWKHURYHUULGHPHWKRGV
IURPWKHVXSHUFODVVRULPSOHPHQWDEVWUDFWPHWKRGVIURPWKHVXSHUFODVV$Q\RWKHU
PHPEHUVLQWKHGHILQLWLRQRIDQDQRQ\PRXVFODVVFDQQRWEHDFFHVVHG
// ...
class Shape implements IDrawable { // (2)
public void draw() { System.out.println("Drawing a Shape."); }
}

class Painter { // (3) Top-level Class


public Shape createShape() { // (4) Non-static Method
return new Shape(){ // (5) Extends superclass
public void draw() { System.out.println("Drawing a new Shape."); }
};
SECTION 7.5: ANONYMOUS CLASSES 245

}
// ...
}
// ...

Implementing an Interface
7KH IROORZLQJ V\QWD[ FDQ EH XVHG IRU GHILQLQJ DQG LQVWDQWLDWLQJ DQ DQRQ\PRXV
FODVVWKDWLPSOHPHQWVDQLQWHUIDFHVSHFLILHGE\LQWHUIDFHQDPH!
new LQWHUIDFHQDPH! () { FODVVGHFODUDWLRQV! }
$Q DQRQ\PRXV FODVV SURYLGHV D VLQJOH LQWHUIDFH LPSOHPHQWDWLRQ DQG QR DUJX
PHQWVDUHSDVVHG7KHDQRQ\PRXVFODVVLPSOLFLWO\H[WHQGVWKH ObjectFODVV1RWH
WKDWQRimplementsFODXVHLVXVHGLQWKHFRQVWUXFW
$Q DQRQ\PRXV FODVV LPSOHPHQWLQJ DQ LQWHUIDFH LV VKRZQ EHORZ 'HWDLOV FDQ EH
IRXQGLQ([DPSOH7KHVWDWLFPHWKRG createIDrawable()DW  GHILQHVD static
DQRQ\PRXVFODVVDW  ZKLFKLPSOHPHQWVWKHLQWHUIDFHIDrawableE\SURYLGLQJDQ
LPSOHPHQWDWLRQRIWKHPHWKRGdraw()7KHIXQFWLRQDOLW\RIREMHFWVRIDQDQRQ\P
RXV FODVV ZKLFK LPSOHPHQWV DQ LQWHUIDFH LV DYDLODEOH WKURXJK UHIHUHQFHV RI WKH
LQWHUIDFHW\SHDQGWKHObjectW\SH
interface IDrawable { // (1)
void draw();
}
// ...
class Painter { // (3) Top-level Class
// ...
public static IDrawable createIDrawable() { // (7) Static Method
return new IDrawable(){ // (8) Implements interface
public void draw() {
System.out.println("Drawing a new IDrawable.");
}
};
}
}
// ...

Instantiating Anonymous Classes


7KHGLVFXVVLRQRQLQVWDQWLDWLQJORFDOFODVVHV ([DPSOH LVDOVRYDOLGIRULQVWDQWL
DWLQJDQRQ\PRXVFODVVHV7KHFODVV ClientLQ([DPSOHFUHDWHVRQHLQVWDQFHDW
 RIWKHQRQVWDWLFDQRQ\PRXVFODVVGHILQHGDW  DQGWZRLQVWDQFHVDW  DQG
 UHVSHFWLYHO\RIWKHVWDWLFDQRQ\PRXVFODVVGHILQHGDW  7KHSURJUDPRXWSXW
VKRZVWKHSRO\PRUSKLFEHKDYLRUDQGWKHUXQWLPHW\SHVRIWKHREMHFWV6LPLODUWRD
QRQVWDWLFORFDOFODVVDQLQVWDQFHRIDQRQVWDWLFDQRQ\PRXVFODVVKDVDQLQVWDQFH
RILWVHQFORVLQJFODVVDW  $QHQFORVLQJLQVWDQFHLVQRWPDQGDWRU\IRUFUHDWLQJ
REMHFWVRIDVWDWLFDQRQ\PRXVFODVVDVVKRZQDW  
246 CHAPTER 7: INNER CLASSES

7KHQDPHVRIWKHDQRQ\PRXVFODVVHVDWUXQWLPHDUHDOVRVKRZQLQWKHSURJUDP
RXWSXW 7KH\ DUH DOVR WKH QDPHV XVHG WR GHVLJQDWH WKHLU UHVSHFWLYH FODVV ILOHV
$QRQ\PRXVFODVVHVDUHQRWVRDQRQ\PRXVDIWHUDOO

Access Rules for Anonymous Classes


$FFHVVUXOHVIRUDQRQ\PRXVFODVVHVDUHWKHVDPHDVIRUORFDOFODVVHV([DPSOH
LV DQ DGDSWDWLRQ RI ([DPSOH  DQG LOOXVWUDWHV WKH DFFHVV UXOHV IRU DQRQ\PRXV
FODVVHV1RQVWDWLFDQRQ\PRXVFODVVHVFDQDFFHVVDOOPHPEHUVLQWKHLUHQFORVLQJ
FRQWH[WDQGDQ\finalYDULDEOHVLQWKHLUORFDOVFRSH,QIDFWLQVLGHWKHGHILQLWLRQRI
DQRQVWDWLFDQRQ\PRXVFODVVREMHFWVRIWKHHQFORVLQJFRQWH[WFDQEHUHIHUHQFHG
XVLQJWKHHQFORVLQJFODVVQDPH!.thisFRQVWUXFW$VIRUVWDWLFDQRQ\PRXVFODVVHV
WKH\FDQRQO\DFFHVVVWDWLFPHPEHUVLQWKHHQFORVLQJFRQWH[WDQGDQ\ finalYDUL
DEOHVLQWKHLUORFDOVFRSH
([DPSOHGHILQHVDQRQVWDWLFDQRQ\PRXVFODVV ZKLFKH[WHQGVWKHVXSHUFODVV
SuperB DW  ZKRVHLQVWDQFHLVDVVLJQHGWRWKHLQVWDQFHYDULDEOHbZKHQWKHFODVV
TopLevelALVLQVWDQWLDWHG$VWDWLFDQRQ\PRXVFODVV ZKLFKDOVRH[WHQGVWKHVXSHU
FODVVSuperB LVGHILQHGDW  DVWKHUHWXUQYDOXHRIWKHVWDWLFPHWKRGstaticMethod()
7KH H[DPSOH LOOXVWUDWHV DOO WKH VLJQLILFDQW FDVHV LQYROYLQJ DFFHVV LQ DQRQ\PRXV
FODVVHV
/LNH ORFDO FODVVHV DQRQ\PRXV FODVVHV FDQQRW KDYH static PHPEHUV DQG WKH\
FDQQRWVSHFLI\DQ\DFFHVVLELOLW\PRGLILHUV7KLVLVVKRZQDW  DQG  

Example 7.10 Access in Anonymous Classes


class SuperB {
protected double x;
protected static int n;
}

class SuperC {
protected double y;
protected static int m;
}
class TopLevelA extends SuperC { // Top-level Class
private double z;
private static int p;
SuperB b = new SuperB() { // (1) Non-static anonymous class
// static double d; // (2) Not OK. Only non-static members allowed.
double zz = TopLevelA.this.z;// (3) non-static from enclosing class.
int pp = p; // (4) static from enclosing class.
double yy = y; // (5) inherited by enclosing class.
int mm = m; // (6) static from enclosing class.
double xx = this.x; // (7) non-static inherited from superclass.
int nn = this.n; // (8) static from superclass.
};
SECTION 7.5: ANONYMOUS CLASSES 247

static SuperB staticMethod(final int i) { // Static Method


final int j = 10;
int k;
return new SuperB() { // (9) Static anonymous class.
// static double d; // (10) Not OK. Only non-static members allowed.
int ii = i; // (11) final from enclosing method.
int jj = j; // (12) final from enclosing method.
// double kk = k; // (13) Not OK. Non-final from enclosing method.
// double zz = TopLevelA.this.z; // (14) Not OK. Non-static member.
int pp = p; // (15) static from enclosing class.
// double yy = y; // (16) Not OK. Non-static member.
int mm = m; // (17) static from enclosing class.
double xx = this.x; // (18) non-static inherited from superclass.
int nn = this.n; // (19) static from superclass.
};
}
}

Review questions

 :KLFKRIWKHIROORZLQJVWDWHPHQWVDUHWUXH"
6HOHFWDOOYDOLGDQVZHUV
D 1RQVWDWLFLQQHUFODVVHVPXVWKDYHHLWKHUGHIDXOWRUpublicDFFHVVLELOLW\
E $OOQHVWHGFODVVHVFDQFRQWDLQRWKHUWRSOHYHOQHVWHGFODVVHV
F 0HWKRGVLQDOOQHVWHGFODVVHVFDQEHGHFODUHGstatic
G $OOQHVWHGFODVVHVFDQEHGHFODUHGstatic
H 7RSOHYHOQHVWHGFODVVHVFDQFRQWDLQQRQVWDWLFPHWKRGV

 *LYHQWKHGHFODUDWLRQ
interface IntHolder { int getInt(); }
ZKLFKRIWKHIROORZLQJPHWKRGVDUHYDOLG"
//----(1)----
IntHolder makeIntHolder(int i) {
return new IntHolder() {
public int getInt() { return i; }
};
}
//----(2)----
IntHolder makeIntHolder(final int i) {
return new IntHolder {
public int getInt() { return i; }
};
}
//----(3)----
IntHolder makeIntHolder(int i) {
class MyIH implements IntHolder {
public int getInt() { return i; }
}
248 CHAPTER 7: INNER CLASSES

return new MyIH();


}
//----(4)----
IntHolder makeIntHolder(final int i) {
class MyIH implements IntHolder {
public int getInt() { return i; }
}
return new MyIH();
}
//----(5)----
IntHolder makeIntHolder(int i) {
return new MyIH(i);
}
static class MyIH implements IntHolder {
final int j;
MyIH(int i) { j = i; }
public int getInt() { return j; }
}

6HOHFWDOOYDOLGDQVZHUV
D 7KHPHWKRGODEHOHG 
E 7KHPHWKRGODEHOHG 
F 7KHPHWKRGODEHOHG 
G 7KHPHWKRGODEHOHG 
H 7KHPHWKRGODEHOHG 

 :KLFKRIWKHVHVWDWHPHQWVDUHWUXH"
6HOHFWDOOYDOLGDQVZHUV
D <RXFDQQRWGHFODUHVWDWLFPHPEHUVZLWKLQDQRQVWDWLFLQQHUFODVV
E ,IDQRQVWDWLFLQQHUFODVVLVQHVWHGZLWKLQDFODVVQDPHG OuterWKHQPHWKRGV
ZLWKLQWKHQRQVWDWLFLQQHUFODVVPXVWXVHWKHSUHIL[ Outer.thisWRDFFHVVWKH
PHPEHUVRIWKHFODVVOuter
F $OOPHPEHUYDULDEOHVLQDQ\QHVWHGFODVVPXVWEHGHFODUHGfinal
G $QRQ\PRXVFODVVHVFDQQRWKDYHFRQVWUXFWRUV
H ,I objRefLVDQLQVWDQFHRIDQ\QHVWHGFODVVZLWKLQWKHFODVVOuterWKHQ (objRef
instanceof Outer)ZRXOG\LHOGWUXH

 :KLFKRIWKHIROORZLQJVWDWHPHQWVDUHWUXH"
6HOHFWDOOYDOLGDQVZHUV
D 3DFNDJHPHPEHUFODVVHVFDQEHGHFODUHGstatic
E &ODVVHVGHFODUHGDVPHPEHUVRIWRSOHYHOFODVVHVFDQEHGHFODUHGstatic
F /RFDOFODVVHVFDQEHGHFODUHGstatic
G $QRQ\PRXVFODVVHVFDQEHGHFODUHGstatic
H 1RFODVVHVFDQEHGHFODUHGstatic
SECTION 7.5: ANONYMOUS CLASSES 249

Chapter summary
7KHIROORZLQJLQIRUPDWLRQZDVLQFOXGHGLQWKLVFKDSWHU
‡ &DWHJRULHVRIQHVWHGFODVVHVWRSOHYHOQHVWHGFODVVHVDQGLQWHUIDFHVQRQVWDWLF
LQQHUFODVVHVORFDOFODVVHVDQRQ\PRXVFODVVHV
‡ 7KHIROORZLQJDVSHFWVSHUWDLQLQJWRQHVWHGFODVVHVDQGLQWHUIDFHVDUHGLVFXVVHG
❍ 7KHFRQWH[WLQZKLFKWKH\FDQEHGHILQHG

❍ :KDWDFFHVVLELOLW\PRGLILHUVDUHYDOLGIRUVXFKFODVVHVDQGLQWHUIDFHV

❍ :KHWKHUDQLQVWDQFHRIWKHRXWHUFRQWH[WLVDVVRFLDWHGZLWKDQLQVWDQFHRIWKH

QHVWHGFODVV
❍ :KDWHQWLWLHVLQLWVRXWHUFRQWH[WDQHVWHGFODVVRULQWHUIDFHFDQDFFHVV

❍ :KHWKHUERWKVWDWLFDQGQRQVWDWLFPHPEHUVFDQEHGHILQHGLQDQHVWHGFODVV

‡ ,PSRUWLQJDQGXVLQJQHVWHGFODVVHVDQGLQWHUIDFHV
‡ $FFHVVLQJ PHPEHUV LQ WKH RXWHU FRQWH[W XVLQJ HQFORVLQJ FODVV QDPH!.this
V\QWD[
‡ ,QVWDQWLDWLQJ LQVWDQFHV RI QHVWHG FODVVHV XVLQJ HQFORVLQJ REMHFW UHIHUHQFH!.new
V\QWD[
‡ 'LVFXVVLRQRIWKHLQKHULWDQFHDQGFRQWDLQPHQWKLHUDUFKLHVRIQHVWHGFODVVHV
‡ ,PSOHPHQWLQJDQRQ\PRXVFODVVHVE\H[WHQGLQJDQH[LVWLQJFODVVDQGE\LPSOH
PHQWLQJDQLQWHUIDFH

Programming exercise

 &UHDWHDQHZSURJUDPZLWKDQHVWHGFODVVQDPHGPrintFuncWKDWH[WHQGVWKHPrint
FODVVLQ([HUFLVH,QDGGLWLRQWRMXVWSULQWLQJWKHYDOXH PrintFuncVKRXOGILUVW
DSSO\DFunctionREMHFWRQWKHYDOXH7KHPrintFuncFODVVVKRXOGKDYHDFRQVWUXFWRU
WKDW WDNHV DQ LQVWDQFH RI Function DV D SDUDPHWHU 7KH evaluate() PHWKRG RI
PrintFuncVKRXOGXVHWKH FunctionREMHFWRQLWVDUJXPHQW7KH evaluate()PHWKRG
VKRXOG SULQW DQG UHWXUQ WKH UHVXOW 7KH evaluate() PHWKRG LQ VXSHUFODVV Print
VKRXOGEHXVHGWRSULQWWKHYDOXH
0DNH WKH SURJUDP EHKDYH MXVW OLNH WKH SURJUDP LQ ([HUFLVH  EXW QRZ XVLQJ
PrintFuncLQVWHDGRIPrint

You might also like