|
| 1 | +/** |
| 2 | + * Static Theory View |
| 3 | + * Comprehensive educational content about static vs instance members |
| 4 | + */ |
| 5 | + |
| 6 | +import styles from './StaticTheory.module.css'; |
| 7 | + |
| 8 | +export function StaticTheory() { |
| 9 | + return ( |
| 10 | + <div className={styles.container}> |
| 11 | + <div className={styles.content}> |
| 12 | + <h2 className={styles.title}>Static vs Non-Static: Deep Dive</h2> |
| 13 | + |
| 14 | + {/* Under the Hood Section */} |
| 15 | + <div className={`${styles.card} ${styles.pink}`}> |
| 16 | + <h3 className={styles.cardTitle}>🔧 Under the Hood: JVM Memory</h3> |
| 17 | + <p className={styles.cardText}> |
| 18 | + When the JVM loads a class, it creates a <strong>Class Object</strong> in |
| 19 | + Metaspace (formerly PermGen). This is where <code>static</code> members live. |
| 20 | + </p> |
| 21 | + <div className={styles.memoryDiagram}> |
| 22 | + <div className={styles.memoryBox}> |
| 23 | + <div className={styles.memoryLabel}>Metaspace</div> |
| 24 | + <div className={styles.memoryContent}> |
| 25 | + <code>Counter.class</code><br /> |
| 26 | + <code>static totalCount = 5</code><br /> |
| 27 | + <code>static getTotalCount()</code> |
| 28 | + </div> |
| 29 | + </div> |
| 30 | + <div className={styles.arrow}>→</div> |
| 31 | + <div className={styles.memoryBox}> |
| 32 | + <div className={styles.memoryLabel}>Heap</div> |
| 33 | + <div className={styles.memoryContent}> |
| 34 | + <code>Counter@0x001</code><br /> |
| 35 | + <code>instanceId = 1</code><br /> |
| 36 | + <code>__class → Counter.class</code> |
| 37 | + </div> |
| 38 | + </div> |
| 39 | + </div> |
| 40 | + </div> |
| 41 | + |
| 42 | + {/* When to Use Static */} |
| 43 | + <div className={`${styles.card} ${styles.green}`}> |
| 44 | + <h3 className={styles.cardTitle}>✅ When to Use Static</h3> |
| 45 | + <ul className={styles.list}> |
| 46 | + <li> |
| 47 | + <strong>Utility Methods:</strong> <code>Math.abs()</code>, <code>Collections.sort()</code> - |
| 48 | + No object state needed, stateless operations |
| 49 | + </li> |
| 50 | + <li> |
| 51 | + <strong>Constants:</strong> <code>static final int MAX_SIZE = 100</code> - |
| 52 | + Values that never change |
| 53 | + </li> |
| 54 | + <li> |
| 55 | + <strong>Counters/IDs:</strong> Track total instances created |
| 56 | + </li> |
| 57 | + <li> |
| 58 | + <strong>Factory Methods:</strong> <code>LocalDate.now()</code>, <code>Optional.of()</code> |
| 59 | + </li> |
| 60 | + <li> |
| 61 | + <strong>Singletons:</strong> Single shared instance pattern |
| 62 | + </li> |
| 63 | + <li> |
| 64 | + <strong>Caching:</strong> Class-level caches shared across all instances |
| 65 | + </li> |
| 66 | + </ul> |
| 67 | + </div> |
| 68 | + |
| 69 | + {/* When NOT to Use Static */} |
| 70 | + <div className={`${styles.card} ${styles.red}`}> |
| 71 | + <h3 className={styles.cardTitle}>❌ When NOT to Use Static</h3> |
| 72 | + <ul className={styles.list}> |
| 73 | + <li> |
| 74 | + <strong>Object State:</strong> Each instance needs its own copy of the data |
| 75 | + </li> |
| 76 | + <li> |
| 77 | + <strong>Polymorphism Needed:</strong> Static methods cannot be overridden |
| 78 | + (only hidden). Use instance methods for strategy pattern. |
| 79 | + </li> |
| 80 | + <li> |
| 81 | + <strong>Testing:</strong> Static state persists between tests, causing flaky tests |
| 82 | + </li> |
| 83 | + <li> |
| 84 | + <strong>Thread Safety:</strong> Shared mutable static state requires synchronization |
| 85 | + </li> |
| 86 | + <li> |
| 87 | + <strong>Dependency Injection:</strong> Static methods can't use injected dependencies |
| 88 | + </li> |
| 89 | + </ul> |
| 90 | + </div> |
| 91 | + |
| 92 | + {/* Thread Safety Warning */} |
| 93 | + <div className={`${styles.card} ${styles.yellow}`}> |
| 94 | + <h3 className={styles.cardTitle}>⚠️ Static & Thread Safety</h3> |
| 95 | + <p className={styles.cardText}> |
| 96 | + Static fields are shared across <strong>ALL threads</strong>. Without synchronization: |
| 97 | + </p> |
| 98 | + <pre className={styles.codeBlock}> |
| 99 | + {`// DANGEROUS - Race condition! |
| 100 | +public class Counter { |
| 101 | + private static int count = 0; |
| 102 | + |
| 103 | + public static void increment() { |
| 104 | + count++; // NOT atomic! |
| 105 | + } |
| 106 | +} |
| 107 | +
|
| 108 | +// SAFE - Use AtomicInteger |
| 109 | +private static AtomicInteger count = new AtomicInteger(0);`} |
| 110 | + </pre> |
| 111 | + </div> |
| 112 | + |
| 113 | + {/* Static Binding */} |
| 114 | + <div className={`${styles.card} ${styles.purple}`}> |
| 115 | + <h3 className={styles.cardTitle}>🔗 Static Binding (Compile-Time)</h3> |
| 116 | + <p className={styles.cardText}> |
| 117 | + Static methods are resolved at <strong>compile time</strong>, not runtime. |
| 118 | + This means polymorphism doesn't work: |
| 119 | + </p> |
| 120 | + <pre className={styles.codeBlock}> |
| 121 | + {`class Animal { |
| 122 | + static void speak() { System.out.println("Animal"); } |
| 123 | +} |
| 124 | +class Dog extends Animal { |
| 125 | + static void speak() { System.out.println("Dog"); } |
| 126 | +} |
| 127 | +
|
| 128 | +Animal a = new Dog(); |
| 129 | +a.speak(); // Prints "Animal", NOT "Dog"! |
| 130 | + // Resolved by reference type, not object type`} |
| 131 | + </pre> |
| 132 | + </div> |
| 133 | + |
| 134 | + {/* Best Practices */} |
| 135 | + <div className={`${styles.card} ${styles.blue}`}> |
| 136 | + <h3 className={styles.cardTitle}>💡 Best Practices</h3> |
| 137 | + <div className={styles.twoColumn}> |
| 138 | + <div> |
| 139 | + <h4 className={styles.subTitle}>Do</h4> |
| 140 | + <ul className={styles.smallList}> |
| 141 | + <li>Use <code>static final</code> for constants</li> |
| 142 | + <li>Make utility classes have private constructor</li> |
| 143 | + <li>Use static factory methods when appropriate</li> |
| 144 | + <li>Document thread-safety guarantees</li> |
| 145 | + </ul> |
| 146 | + </div> |
| 147 | + <div> |
| 148 | + <h4 className={styles.subTitle}>Don't</h4> |
| 149 | + <ul className={styles.smallList}> |
| 150 | + <li>Use static mutable state liberally</li> |
| 151 | + <li>Use static to avoid passing parameters</li> |
| 152 | + <li>Overuse static for "convenience"</li> |
| 153 | + <li>Mix static initialization with side effects</li> |
| 154 | + </ul> |
| 155 | + </div> |
| 156 | + </div> |
| 157 | + </div> |
| 158 | + |
| 159 | + {/* Static Initialization */} |
| 160 | + <div className={`${styles.card} ${styles.indigo}`}> |
| 161 | + <h3 className={styles.cardTitle}>📦 Static Initialization Order</h3> |
| 162 | + <pre className={styles.codeBlock}> |
| 163 | + {`class Example { |
| 164 | + // 1. Static fields initialized first (in order) |
| 165 | + static int x = 10; |
| 166 | + |
| 167 | + // 2. Static block runs after fields |
| 168 | + static { |
| 169 | + System.out.println("Static block: x = " + x); |
| 170 | + x = 20; |
| 171 | + } |
| 172 | + |
| 173 | + // 3. Instance initialization happens on new |
| 174 | + int y = 30; |
| 175 | + { System.out.println("Instance block"); } |
| 176 | + |
| 177 | + // 4. Constructor runs last |
| 178 | + Example() { System.out.println("Constructor"); } |
| 179 | +}`} |
| 180 | + </pre> |
| 181 | + <p className={styles.cardNote}> |
| 182 | + Static initialization happens <strong>once</strong> when class is first loaded. |
| 183 | + </p> |
| 184 | + </div> |
| 185 | + |
| 186 | + </div> |
| 187 | + </div> |
| 188 | + ); |
| 189 | +} |
0 commit comments