|
1 | 1 | { |
2 | 2 | "lessonId": "java-2-3", |
3 | | - "title": "Optional 사용법", |
4 | | - "concept": "Optional은 null 대신 '값이 없을 수 있음'을 명시적으로 표현한다", |
| 3 | + "title": "可选用途", |
| 4 | + "concept": "可选明确表达“可能没有值”而不是 null。", |
5 | 5 | "content": { |
6 | 6 | "code": "Optional<String> opt1 = Optional.of(\"hello\");\nOptional<String> opt2 = Optional.empty();\nOptional<String> opt3 = Optional.ofNullable(null);\n\nString value = opt1.get();\n\nif (opt2.isPresent()) {\n System.out.println(opt2.get());\n}\n\nString result = opt3.orElse(\"default\");\n\nopt1.ifPresent(s -> System.out.println(s));", |
7 | 7 | "steps": [ |
8 | 8 | { |
9 | | - "title": "Optional.of() - 상자 만들기", |
10 | | - "explanation": "**실행 순서:**\n1. `Optional.of(\"hello\")` 호출.\n2. Heap에 `Optional` 객체(상자) 생성.\n3. 내부에 \"hello\" 값 저장.\n\n**메모리에서 일어나는 일:**\nHeap에 `Optional`이라는 **단단한 상자(Wrapper)**를 만들고, \"hello\" 문자열을 그 상자 안에 안전하게 넣습니다.\n\n**경고:** `of()`는 `null`을 절대 허용하지 않습니다.\nnull을 넣으면 상자를 만들기도 전에 NPE가 터집니다.", |
11 | | - "keyInsight": "of() = null 절대 불가", |
| 9 | + "title": "Optional.of() - 创建一个盒子", |
| 10 | + "explanation": "**执行顺序:**\n1. 调用 `Optional.of(\"hello\")`。\n2. 在堆中创建一个“Optional”对象(框)。\n3. 在内部存储“hello”值。\n\n**内存中发生了什么:**\n在堆上创建一个名为“Optional”的**硬包装**,并将字符串“hello”安全地放置在框中。\n\n**警告:** `of()` 绝不允许 `null`。\n如果输入 null,则在创建框之前就会发生 NPE。", |
| 11 | + "keyInsight": "of() = 永不为空", |
12 | 12 | "visualizationType": "javaMemory", |
13 | 13 | "code": "Optional<String> opt1 = Optional.of(\"hello\");", |
14 | 14 | "javaMemoryState": { |
|
35 | 35 | } |
36 | 36 | }, |
37 | 37 | { |
38 | | - "title": "Optional.empty() - 빈 상자", |
39 | | - "explanation": "**실행 순서:**\n1. `Optional.empty()` 호출.\n2. 비어있는 `Optional` 객체 반환.\n\n내용물이 없는 '빈 상자' 객체를 만듭니다.\n`null` 변수를 쓰는 대신 \"상자는 있는데 내용은 없어\"라고 명확하게 말하는 방식입니다.\n`Optional`을 리턴하면 \"아, 없을 수도 있구나\"라고 바로 알 수 있습니다.", |
40 | | - "keyInsight": "empty() = 값 없음을 명시적으로 표현", |
| 38 | + "title": "Optional.empty() - 空框", |
| 39 | + "explanation": "**执行顺序:**\n1. 调用`Optional.empty()`。\n2. 返回一个空的`Optional`对象。\n\n创建一个没有内容的“空盒子”对象。\n这是一种清楚地说“我有一个盒子,但没有内容”的方法,而不是使用“null”变量。\n返回“Optional”会让你立即知道,“哦,也许它不在那里。”", |
| 40 | + "keyInsight": "empty() = 明确表示没有值", |
41 | 41 | "visualizationType": "javaMemory", |
42 | 42 | "code": "Optional<String> opt2 = Optional.empty();", |
43 | 43 | "javaMemoryState": { |
|
67 | 67 | } |
68 | 68 | }, |
69 | 69 | { |
70 | | - "title": "Optional.ofNullable() - 유연한 상자", |
71 | | - "explanation": "**실행 순서:**\n1. `Optional.ofNullable(null)` 호출.\n2. 인자가 `null`임 확인.\n3. 내부적으로 `Optional.empty()` 반환.\n\n값이 있으면 상자에 넣고(`of`), `null`이면 빈 상자(`empty`)를 만듭니다.\n현실적으로 가장 많이 쓰이는 생성 방식입니다.", |
| 70 | + "title": "Optional.ofNullable() - 灵活的盒子", |
| 71 | + "explanation": "**执行顺序:**\n1. 调用`Optional.ofNullable(null)`。\n2. 确认参数为“null”。\n3. 内部返回`Optional.empty()`。\n\n如果该值存在,则将其放置在框中 (`of`) 中。如果它是“null”,则创建一个空框(“empty”)。\nIn reality, this is the most commonly used creation method.", |
72 | 72 | "visualizationType": "javaMemory", |
73 | 73 | "code": "Optional<String> opt3 = Optional.ofNullable(null);", |
74 | 74 | "javaMemoryState": { |
|
90 | 90 | } |
91 | 91 | }, |
92 | 92 | { |
93 | | - "title": "get() - 강제로 꺼내기 (위험!!)", |
94 | | - "explanation": "**실행 순서:**\n1. `opt1.get()` 호출.\n2. 값 존재 확인.\n3. \"hello\" 반환.\n\n상자를 무작정 엽니다.\n지금은 값이 있어서 다행이지만, 비어있을 때 `get()`을 호출하면 **`NoSuchElementException`** 예외가 폭발합니다.\n\n**경고:** `get()`은 최후의 수단입니다.\n되도록 쓰지 마세요.", |
95 | | - "keyInsight": "get() 대신 orElse() 사용 권장", |
| 93 | + "title": "get() - 强制弹出(危险!!)", |
| 94 | + "explanation": "**执行顺序:**\n1. 调用`opt1.get()`。\n2. 检查是否存在价值。\n3.返回“你好”。\n\n我盲目地打开盒子。\n我很高兴我现在有了这个值,但是如果我在它为空时调用 `get()` ,它会抛出 **`NoSuchElementException`** 异常。\n\n**警告:** `get()` 是最后的手段。\n尽可能避免使用它。", |
| 95 | + "keyInsight": "推荐使用 orElse() 而不是 get()", |
96 | 96 | "visualizationType": "javaMemory", |
97 | 97 | "code": "String value = opt1.get();", |
98 | 98 | "javaMemoryState": { |
|
107 | 107 | } |
108 | 108 | }, |
109 | 109 | { |
110 | | - "title": "isPresent() - 확인하기", |
111 | | - "explanation": "**실행 순서:**\n1. `opt2.isPresent()` 호출.\n2. `opt2`는 empty이므로 **false** 반환.\n3. `if` 블록 건너뜀.\n\n\"상자에 값이 있나요?\"(`isPresent`) 라고 물어봅니다.\n`opt2`는 비어있으므로 `false`를 반환하고, `if` 블록은 실행되지 않습니다.", |
| 110 | + "title": "isPresent() - 检查", |
| 111 | + "explanation": "**执行顺序:**\n1. 调用`opt2.isPresent()`。\n2. `opt2` 为空,因此返回**false**。\n3. 跳过“if”块。\n\n它询问“这个盒子有价值吗?” (“存在”)。\n由于“opt2”为空,因此返回“false”,并且不执行“if”块。", |
112 | 112 | "visualizationType": "javaMemory", |
113 | 113 | "code": "if (opt2.isPresent()) {", |
114 | 114 | "javaMemoryState": { |
115 | 115 | "note": "opt2는 empty이므로 false 반환, 블록 실행 안 됨" |
116 | 116 | } |
117 | 117 | }, |
118 | 118 | { |
119 | | - "title": "orElse() - 안전한 기본값 제공", |
120 | | - "explanation": "**실행 순서:**\n1. `opt3.orElse(\"default\")` 호출.\n2. `opt3`가 비어있음 확인.\n3. 인자로 넘긴 `\"default\"` 반환.\n\n**가장 권장하는 방식:** \"상자를 열어봐.\n값이 있으면 그거 쓰고, **비어있으면 'default'를 대신 써.**\"\n한 줄로 깔끔하고 안전하게 값을 얻을 수 있습니다.", |
121 | | - "keyInsight": "orElse() = 안전한 기본값 패턴", |
| 119 | + "title": "orElse() - 提供安全的默认值", |
| 120 | + "explanation": "**执行顺序:**\n1. 调用`opt3.orElse(\"default\")`。\n2. 检查“opt3”是否为空。\n3. 返回作为参数传递的“默认”。\n\n**最推荐的方法:** 《打开盒子。\n如果有一个值,就使用它。 **如果为空,则使用“默认”。**”\n您可以在一行中整齐、安全地获取该值。", |
| 121 | + "keyInsight": "orElse() = 安全默认模式", |
122 | 122 | "visualizationType": "javaMemory", |
123 | 123 | "code": "String result = opt3.orElse(\"default\");", |
124 | 124 | "javaMemoryState": { |
|
133 | 133 | } |
134 | 134 | }, |
135 | 135 | { |
136 | | - "title": "ifPresent() - 함수형 스타일", |
137 | | - "explanation": "**실행 순서:**\n1. `opt1.ifPresent(...)` 호출.\n2. `opt1`에 값이 있음 확인.\n3. 람다 함수 `s -> println(s)` 실행.\n4. \"hello\" 출력.\n\n\"값이 있으면 이 함수(람다)를 실행 해줘.\n없으면 말고.\"\n값을 꺼내지 않고, 상자 안에서 작업을 처리하도록 시키는 세련된 방법입니다.", |
138 | | - "keyInsight": "ifPresent() = 값 있을 때만 실행", |
| 136 | + "title": "ifPresent() - 函数式风格", |
| 137 | + "explanation": "**执行顺序:**\n1. 调用`opt1.ifPresent(...)`。\n2. 确认“opt1”具有值。\n3. 执行 lambda 函数 `s -> println(s)`。\n4. 输出“你好”。\n\n“如果有值,则执行这个函数(lambda)。\n“Not if you don’t have it.”\n这是一种在盒子内做事的优雅方式,无需拉出值。", |
| 138 | + "keyInsight": "ifPresent() = 仅当有值时执行", |
139 | 139 | "visualizationType": "javaMemory", |
140 | 140 | "code": "opt1.ifPresent(s -> System.out.println(s));", |
141 | 141 | "javaMemoryState": { |
|
161 | 161 | }, |
162 | 162 | "misconceptions": [ |
163 | 163 | { |
164 | | - "wrong": "Optional은 null 처리를 완전히 대체한다", |
165 | | - "correct": "아닙니다.\nOptional 변수 자체가 null일 수도 있습니다(최악의 상황).", |
166 | | - "why": "Optional을 쓰려면 `Optional<String> opt = null;` 절대 이러지 말고, 항상 `Optional.empty()`로 초기화해야 합니다." |
| 164 | + "wrong": "可选完全取代空处理", |
| 165 | + "correct": "不。\n可选变量本身可能为空(最坏的情况)。", |
| 166 | + "why": "要使用Optional,您永远不应该使用“Optional<String> opt = null;”,并始终使用“Optional.empty()”对其进行初始化。" |
167 | 167 | }, |
168 | 168 | { |
169 | | - "wrong": "isPresent() + get() 패턴이 정석이다", |
170 | | - "correct": "`orElse()`나 `ifPresent()` 같은 메서드를 쓰는 게 'Optional스러운' 사용법입니다.", |
171 | | - "why": "`if (opt.isPresent()) { ... get() }`은 `if (x != null)`과 다를 바가 없어서 코드가 장황해집니다.\nOptional의 진가는 함수형 스타일에 있습니다." |
| 169 | + "wrong": "isPresent() + get() 模式是标准的。", |
| 170 | + "correct": "使用“orElse()”或“ifPresent()”等方法是“可选”用法。", |
| 171 | + "why": "`if (opt.isPresent()) { ... get() }` 与 `if (x != null)` 没有什么不同,这使得代码变得冗长。\nOptional 的真正价值在于它的函数式风格。" |
172 | 172 | } |
173 | 173 | ], |
174 | | - "keyTakeaway": "리턴 타입에는 Optional, 꺼낼 때는 orElse()!" |
| 174 | + "keyTakeaway": "返回类型可选,取出时orElse()!" |
175 | 175 | } |
0 commit comments