-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnestedinnerclass.html
More file actions
176 lines (155 loc) · 6.79 KB
/
Copy pathnestedinnerclass.html
File metadata and controls
176 lines (155 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Java Revision: Non-Static Inner Classes</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f4f7f6;
color: #333;
line-height: 1.6;
padding: 20px;
}
.container {
max-width: 800px;
margin: auto;
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
border-top: 5px solid #86bc25; /* Deloitte Green Accent */
}
h1 {
color: #000;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
h2 {
color: #86bc25;
margin-top: 30px;
border-bottom: 1px solid #eee;
padding-bottom: 5px;
}
h3 {
color: #444;
}
p {
margin-bottom: 15px;
}
ul {
margin-bottom: 20px;
}
li {
margin-bottom: 10px;
}
pre {
background-color: #2b2b2b;
color: #f8f8f2;
padding: 15px;
border-radius: 5px;
overflow-x: auto;
font-size: 14px;
}
code {
font-family: Consolas, Monaco, 'Andale Mono', monospace;
}
.highlight {
font-weight: bold;
color: #005587;
}
.warning {
background-color: #fff3cd;
color: #856404;
padding: 15px;
border-left: 5px solid #ffeeba;
margin: 20px 0;
border-radius: 4px;
}
.rule-of-thumb {
background-color: #d4edda;
color: #155724;
padding: 15px;
border-left: 5px solid #c3e6cb;
margin: 20px 0;
border-radius: 4px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1>Java Revision: Non-Static Inner Classes</h1>
<h2>Core Concept & Purpose</h2>
<p>A <strong>non-static inner class</strong> (also known as a <strong>member inner class</strong>) is a nested class defined within another class without the <code>static</code> modifier.</p>
<p>The defining characteristic of a non-static inner class is that <span class="highlight">an instance of it is always implicitly associated with a specific instance of the outer class</span>. It has direct access to all variables and methods of its outer class, including those marked as <code>private</code>.</p>
<h2>Key Use Cases</h2>
<h3>1. Logical Grouping of Helper Classes</h3>
<p>When a class is useful only within the context of another class, nesting it logically groups them together. This keeps the codebase cleaner and prevents the package namespace from being cluttered with specialized, single-use classes.</p>
<h3>2. Representing "Part-Of" Relationships with Direct State Access</h3>
<p>If you have an object that represents a sub-component of a larger entity and needs to dynamically read or modify the parent entity's state, a non-static inner class is ideal.</p>
<ul>
<li><strong>Example:</strong> A <code>BankAccount</code> class has a nested <code>Transaction</code> class. Each transaction needs direct access to the specific account's private balance to update it.</li>
</ul>
<pre><code>public class BankAccount {
private double balance;
private String accountNumber;
public BankAccount(String accountNumber, double initialBalance) {
this.accountNumber = accountNumber;
this.balance = initialBalance;
}
// Non-static inner class
public class Transaction {
private double amount;
public Transaction(double amount) {
this.amount = amount;
}
public void execute() {
// Directly accesses and modifies the outer class's private field
balance += amount;
System.out.println("Account " + accountNumber + " new balance: $" + balance);
}
}
}</code></pre>
<h3>3. Implementing Clean Adapters (e.g., Iterators)</h3>
<p>Java's Collections Framework heavily relies on non-static inner classes to implement iterators. An iterator needs to traverse a collection, which requires direct access to the private data structures (like arrays or linked nodes) of the outer collection instance.</p>
<pre><code>public class CustomList {
private Object[] elements;
// Returns an instance of the inner class
public Iterator iterator() {
return new ListIterator();
}
// Inner class implementing the Iterator interface
private class ListIterator implements Iterator {
private int currentIndex = 0;
@Override
public boolean hasNext() {
// Directly accesses elements array of the outer class instance
return currentIndex < elements.length;
}
@Override
public Object next() {
return elements[currentIndex++];
}
}
}</code></pre>
<h3>4. Enhancing Encapsulation</h3>
<p>By making the non-static inner class <code>private</code> or <code>protected</code>, you can completely hide complex implementation details from the outside world. External classes can interact with the inner class only through interfaces publically exposed by the outer class.</p>
<h2>⚠️ Critical Watch-outs & Pitfalls</h2>
<div class="warning">
<ul>
<li><strong>Memory Leaks:</strong> Because every non-static inner class instance holds an implicit reference to its outer class instance, the outer class instance <strong>cannot be garbage collected</strong> as long as the inner class instance is still referenced. If you pass an inner class object to a long-lived thread or cache, you might accidentally leak the entire outer class.</li>
<li><strong>Performance Overhead:</strong> The implicit reference to the outer class adds a tiny amount of memory overhead per instance.</li>
<li><strong>Creation Syntax:</strong> You cannot instantiate a non-static inner class without an outer class instance.</li>
</ul>
<pre><code>// Syntax for instantiation:
BankAccount account = new BankAccount("12345", 1000.0);
BankAccount.Transaction transaction = account.new Transaction(250.0);</code></pre>
</div>
<div class="rule-of-thumb">
📌 Rule of Thumb: If the nested class does not require access to the instance variables or methods of the outer class, always declare it `static` (making it a Static Nested Class) to avoid the implicit outer reference and prevent potential memory leaks.
</div>
</div>
</body>
</html>