autosnippet 3.0.0 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +230 -324
- package/bin/api-server.js +1 -1
- package/bin/cli.js +204 -244
- package/bin/mcp-server.js +5 -3
- package/config/knowledge-base.config.js +132 -132
- package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
- package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
- package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/bootstrap.js +8 -8
- package/lib/cli/AiScanService.js +86 -40
- package/lib/cli/KnowledgeSyncService.js +113 -74
- package/lib/cli/SetupService.js +439 -277
- package/lib/cli/UpgradeService.js +63 -100
- package/lib/core/AstAnalyzer.js +276 -597
- package/lib/core/ast/ProjectGraph.js +101 -40
- package/lib/core/ast/ensure-grammars.js +232 -0
- package/lib/core/ast/index.js +115 -0
- package/lib/core/ast/lang-dart.js +661 -0
- package/lib/core/ast/lang-go.js +530 -0
- package/lib/core/ast/lang-java.js +435 -0
- package/lib/core/ast/lang-javascript.js +272 -0
- package/lib/core/ast/lang-kotlin.js +423 -0
- package/lib/core/ast/lang-objc.js +388 -0
- package/lib/core/ast/lang-python.js +371 -0
- package/lib/core/ast/lang-swift.js +337 -0
- package/lib/core/ast/lang-typescript.js +503 -0
- package/lib/core/capability/CapabilityProbe.js +18 -9
- package/lib/core/constitution/Constitution.js +2 -3
- package/lib/core/constitution/ConstitutionValidator.js +65 -24
- package/lib/core/discovery/DartDiscoverer.js +534 -0
- package/lib/core/discovery/DiscovererRegistry.js +83 -0
- package/lib/core/discovery/GenericDiscoverer.js +225 -0
- package/lib/core/discovery/GoDiscoverer.js +541 -0
- package/lib/core/discovery/JvmDiscoverer.js +506 -0
- package/lib/core/discovery/NodeDiscoverer.js +466 -0
- package/lib/core/discovery/ProjectDiscoverer.js +93 -0
- package/lib/core/discovery/PythonDiscoverer.js +338 -0
- package/lib/core/discovery/SpmDiscoverer.js +5 -0
- package/lib/core/discovery/index.js +53 -0
- package/lib/core/enhancement/EnhancementPack.js +71 -0
- package/lib/core/enhancement/EnhancementRegistry.js +47 -0
- package/lib/core/enhancement/android-enhancement.js +102 -0
- package/lib/core/enhancement/django-enhancement.js +70 -0
- package/lib/core/enhancement/fastapi-enhancement.js +63 -0
- package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
- package/lib/core/enhancement/go-web-enhancement.js +201 -0
- package/lib/core/enhancement/index.js +65 -0
- package/lib/core/enhancement/node-server-enhancement.js +88 -0
- package/lib/core/enhancement/react-enhancement.js +86 -0
- package/lib/core/enhancement/spring-enhancement.js +112 -0
- package/lib/core/enhancement/vue-enhancement.js +96 -0
- package/lib/core/gateway/Gateway.js +8 -9
- package/lib/core/gateway/GatewayActionRegistry.js +1 -1
- package/lib/core/permission/PermissionManager.js +12 -8
- package/lib/domain/index.js +13 -9
- package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
- package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
- package/lib/domain/knowledge/Lifecycle.js +22 -22
- package/lib/domain/knowledge/index.js +9 -12
- package/lib/domain/knowledge/values/Constraints.js +31 -21
- package/lib/domain/knowledge/values/Content.js +21 -13
- package/lib/domain/knowledge/values/Quality.js +31 -18
- package/lib/domain/knowledge/values/Reasoning.js +20 -12
- package/lib/domain/knowledge/values/Relations.js +37 -25
- package/lib/domain/knowledge/values/Stats.js +18 -12
- package/lib/domain/knowledge/values/index.js +4 -3
- package/lib/domain/snippet/Snippet.js +35 -10
- package/lib/external/ai/AiFactory.js +48 -16
- package/lib/external/ai/AiProvider.js +184 -90
- package/lib/external/ai/providers/ClaudeProvider.js +25 -12
- package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
- package/lib/external/ai/providers/MockProvider.js +9 -3
- package/lib/external/ai/providers/OpenAiProvider.js +51 -29
- package/lib/external/mcp/McpServer.js +66 -36
- package/lib/external/mcp/errorHandler.js +23 -11
- package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
- package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
- package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
- package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
- package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
- package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
- package/lib/external/mcp/handlers/bootstrap.js +691 -168
- package/lib/external/mcp/handlers/browse.js +66 -22
- package/lib/external/mcp/handlers/candidate.js +118 -35
- package/lib/external/mcp/handlers/consolidated.js +49 -17
- package/lib/external/mcp/handlers/guard.js +104 -39
- package/lib/external/mcp/handlers/knowledge.js +60 -36
- package/lib/external/mcp/handlers/search.js +43 -14
- package/lib/external/mcp/handlers/skill.js +120 -45
- package/lib/external/mcp/handlers/structure.js +240 -86
- package/lib/external/mcp/handlers/system.js +42 -12
- package/lib/external/mcp/handlers/wiki.js +58 -33
- package/lib/external/mcp/tools.js +306 -123
- package/lib/http/HttpServer.js +72 -47
- package/lib/http/middleware/RateLimiter.js +5 -3
- package/lib/http/middleware/errorHandler.js +6 -1
- package/lib/http/middleware/requestLogger.js +14 -3
- package/lib/http/middleware/roleResolver.js +30 -23
- package/lib/http/routes/ai.js +387 -265
- package/lib/http/routes/auth.js +81 -61
- package/lib/http/routes/candidates.js +430 -320
- package/lib/http/routes/commands.js +289 -189
- package/lib/http/routes/extract.js +158 -125
- package/lib/http/routes/guardRules.js +309 -217
- package/lib/http/routes/knowledge.js +213 -154
- package/lib/http/routes/modules.js +578 -0
- package/lib/http/routes/monitoring.js +6 -6
- package/lib/http/routes/recipes.js +104 -93
- package/lib/http/routes/search.js +361 -305
- package/lib/http/routes/skills.js +145 -98
- package/lib/http/routes/snippets.js +42 -30
- package/lib/http/routes/spm.js +3 -405
- package/lib/http/routes/violations.js +113 -93
- package/lib/http/routes/wiki.js +211 -170
- package/lib/http/utils/routeHelpers.js +3 -1
- package/lib/http/utils/sse-sessions.js +16 -6
- package/lib/http/utils/sse.js +15 -5
- package/lib/infrastructure/audit/AuditLogger.js +5 -2
- package/lib/infrastructure/audit/AuditStore.js +10 -7
- package/lib/infrastructure/cache/CacheService.js +3 -1
- package/lib/infrastructure/cache/GraphCache.js +8 -4
- package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
- package/lib/infrastructure/config/ConfigLoader.js +9 -5
- package/lib/infrastructure/config/Defaults.js +30 -10
- package/lib/infrastructure/config/Paths.js +28 -8
- package/lib/infrastructure/config/TriggerSymbol.js +22 -10
- package/lib/infrastructure/database/DatabaseConnection.js +15 -10
- package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
- package/lib/infrastructure/external/ClipboardManager.js +6 -2
- package/lib/infrastructure/external/NativeUi.js +50 -43
- package/lib/infrastructure/external/OpenBrowser.js +14 -17
- package/lib/infrastructure/external/XcodeAutomation.js +14 -258
- package/lib/infrastructure/logging/Logger.js +46 -30
- package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
- package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
- package/lib/infrastructure/paths/HeaderResolver.js +25 -9
- package/lib/infrastructure/paths/PathFinder.js +34 -12
- package/lib/infrastructure/plugin/PluginManager.js +26 -8
- package/lib/infrastructure/realtime/RealtimeService.js +2 -2
- package/lib/infrastructure/vector/Chunker.js +22 -7
- package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
- package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
- package/lib/infrastructure/vector/VectorStore.js +28 -10
- package/lib/injection/ServiceContainer.js +247 -93
- package/lib/platform/ios/index.js +63 -0
- package/lib/platform/ios/routes/spm.js +437 -0
- package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
- package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
- package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
- package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
- package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
- package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
- package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
- package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
- package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
- package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
- package/lib/repository/base/BaseRepository.js +7 -9
- package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
- package/lib/repository/token/TokenUsageStore.js +4 -2
- package/lib/service/automation/ActionPipeline.js +1 -1
- package/lib/service/automation/AutomationOrchestrator.js +8 -4
- package/lib/service/automation/ContextCollector.js +7 -5
- package/lib/service/automation/DirectiveDetector.js +23 -16
- package/lib/service/automation/FileWatcher.js +112 -56
- package/lib/service/automation/TriggerResolver.js +6 -4
- package/lib/service/automation/handlers/AlinkHandler.js +24 -12
- package/lib/service/automation/handlers/CreateHandler.js +19 -20
- package/lib/service/automation/handlers/DraftHandler.js +14 -8
- package/lib/service/automation/handlers/GuardHandler.js +93 -63
- package/lib/service/automation/handlers/HeaderHandler.js +1 -6
- package/lib/service/automation/handlers/SearchHandler.js +155 -88
- package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
- package/lib/service/candidate/SimilarityService.js +25 -9
- package/lib/service/chat/AnalystAgent.js +50 -24
- package/lib/service/chat/CandidateGuardrail.js +143 -17
- package/lib/service/chat/ChatAgent.js +759 -243
- package/lib/service/chat/ContextWindow.js +116 -71
- package/lib/service/chat/ConversationStore.js +77 -36
- package/lib/service/chat/EpisodicConsolidator.js +47 -23
- package/lib/service/chat/HandoffProtocol.js +98 -22
- package/lib/service/chat/Memory.js +34 -14
- package/lib/service/chat/ProducerAgent.js +40 -20
- package/lib/service/chat/ProjectSemanticMemory.js +109 -78
- package/lib/service/chat/ReasoningLayer.js +148 -70
- package/lib/service/chat/ReasoningTrace.js +44 -32
- package/lib/service/chat/TaskPipeline.js +39 -19
- package/lib/service/chat/ToolRegistry.js +48 -29
- package/lib/service/chat/WorkingMemory.js +44 -18
- package/lib/service/chat/tools.js +1096 -494
- package/lib/service/context/RecipeExtractor.js +132 -51
- package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
- package/lib/service/cursor/KnowledgeCompressor.js +25 -22
- package/lib/service/cursor/RulesGenerator.js +13 -7
- package/lib/service/cursor/SkillsSyncer.js +77 -27
- package/lib/service/cursor/TokenBudget.js +2 -2
- package/lib/service/cursor/TopicClassifier.js +54 -20
- package/lib/service/guard/ComplianceReporter.js +55 -43
- package/lib/service/guard/ExclusionManager.js +67 -29
- package/lib/service/guard/GuardCheckEngine.js +381 -86
- package/lib/service/guard/GuardFeedbackLoop.js +22 -10
- package/lib/service/guard/GuardService.js +29 -19
- package/lib/service/guard/RuleLearner.js +55 -23
- package/lib/service/guard/SourceFileCollector.js +27 -20
- package/lib/service/guard/ViolationsStore.js +43 -38
- package/lib/service/knowledge/CodeEntityGraph.js +147 -82
- package/lib/service/knowledge/ConfidenceRouter.js +12 -10
- package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
- package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
- package/lib/service/knowledge/KnowledgeService.js +222 -112
- package/lib/service/module/ModuleService.js +969 -0
- package/lib/service/quality/FeedbackCollector.js +27 -15
- package/lib/service/quality/QualityScorer.js +78 -24
- package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
- package/lib/service/recipe/RecipeParser.js +78 -45
- package/lib/service/search/CoarseRanker.js +43 -28
- package/lib/service/search/CrossEncoderReranker.js +32 -21
- package/lib/service/search/InvertedIndex.js +21 -7
- package/lib/service/search/MultiSignalRanker.js +90 -28
- package/lib/service/search/RetrievalFunnel.js +45 -24
- package/lib/service/search/SearchEngine.js +255 -103
- package/lib/service/skills/EventAggregator.js +32 -15
- package/lib/service/skills/SignalCollector.js +140 -64
- package/lib/service/skills/SkillAdvisor.js +79 -42
- package/lib/service/skills/SkillHooks.js +16 -14
- package/lib/service/snippet/PlaceholderConverter.js +5 -0
- package/lib/service/snippet/SnippetFactory.js +116 -99
- package/lib/service/snippet/SnippetInstaller.js +234 -62
- package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
- package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
- package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
- package/lib/service/wiki/WikiGenerator.js +637 -263
- package/lib/shared/DimensionCopyRegistry.js +472 -0
- package/lib/shared/LanguageService.js +399 -0
- package/lib/shared/PathGuard.js +45 -28
- package/lib/shared/RecipeReadinessChecker.js +72 -12
- package/lib/shared/constants.js +41 -41
- package/lib/shared/errors/BaseError.js +2 -2
- package/lib/shared/errors/index.js +4 -4
- package/lib/shared/similarity.js +25 -8
- package/lib/shared/token-utils.js +6 -2
- package/lib/shared/utils/common.js +12 -4
- package/package.json +49 -13
- package/scripts/bench-real-projects.mjs +256 -0
- package/scripts/build-native-ui.js +30 -30
- package/scripts/clear-old-vector-index.js +5 -35
- package/scripts/clear-vector-cache.js +7 -37
- package/scripts/collect-test-project-stats.mjs +160 -0
- package/scripts/diagnose-mcp.js +41 -32
- package/scripts/ensure-parse-package.js +6 -9
- package/scripts/generate-recipe-drafts.js +116 -77
- package/scripts/init-db.js +3 -20
- package/scripts/init-snippets.js +305 -0
- package/scripts/init-vector-db.js +173 -170
- package/scripts/install-cursor-skill.js +148 -104
- package/scripts/install-full.js +8 -21
- package/scripts/install-vscode-copilot.js +146 -145
- package/scripts/migrate-md-to-knowledge.mjs +139 -151
- package/scripts/postinstall-safe.js +5 -17
- package/scripts/recipe-audit.js +106 -82
- package/scripts/release.js +283 -323
- package/scripts/setup-mcp-config.js +60 -52
- package/scripts/verify-context-api.js +20 -20
- package/skills/autosnippet-analysis/SKILL.md +10 -6
- package/skills/autosnippet-candidates/SKILL.md +27 -26
- package/skills/autosnippet-coldstart/SKILL.md +555 -38
- package/skills/autosnippet-concepts/SKILL.md +349 -337
- package/skills/autosnippet-create/SKILL.md +5 -5
- package/skills/autosnippet-reference-dart/SKILL.md +543 -0
- package/skills/autosnippet-reference-go/SKILL.md +539 -0
- package/skills/autosnippet-reference-java/SKILL.md +534 -0
- package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
- package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
- package/skills/autosnippet-reference-objc/SKILL.md +29 -6
- package/skills/autosnippet-reference-python/SKILL.md +800 -0
- package/skills/autosnippet-reference-swift/SKILL.md +70 -14
- package/skills/autosnippet-structure/SKILL.md +4 -4
- package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
- package/templates/recipes-setup/README.md +2 -2
- package/templates/recipes-setup/_template.md +1 -1
- package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
- package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
- package/resources/asd-entry/main.swift +0 -159
- package/scripts/build-asd-entry.js +0 -51
- package/scripts/init-xcode-snippets.js +0 -311
- package/template.json +0 -39
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: autosnippet-reference-java
|
|
3
|
+
description: Java 业界最佳实践参考。涵盖 OOP 设计、泛型、Optional、注解、异常处理、并发、Stream API、Record、不可变性、命名约定,为冷启动分析提供高质量参考标准。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Java 最佳实践参考 (Industry Reference)
|
|
7
|
+
|
|
8
|
+
> 本 Skill 为 **autosnippet-coldstart** 的 Companion Skill。在冷启动分析 Java 项目时,请参考以下业界标准产出高质量候选。
|
|
9
|
+
> **来源**: Google Java Style Guide, Effective Java 3rd Ed. (Bloch), Spring Framework Best Practices, JEP/JDK Release Notes
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. 包结构与导入
|
|
14
|
+
|
|
15
|
+
### 核心规则
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"title": "Java: 按功能分包 + 导入规范",
|
|
20
|
+
"content": {
|
|
21
|
+
"markdown": "## Java: 按功能分包 + 导入规范\n\n### 标准模式\n```java\n// ✅ 按功能分包 (Feature-based, 推荐)\ncom.example.app\n├── user/\n│ ├── UserController.java\n│ ├── UserService.java\n│ ├── UserRepository.java\n│ └── UserDto.java\n├── order/\n│ ├── OrderController.java\n│ └── OrderService.java\n└── common/\n ├── exception/\n └── config/\n\n// ❌ 按层分包 (Layer-based, 不推荐)\ncom.example.app\n├── controller/ // 所有 controller 混在一起\n├── service/\n├── repository/\n└── dto/\n\n// ✅ 导入规范 (Google Java Style §3.3)\nimport com.example.app.user.User; // 具体类导入\nimport java.util.List; // 标准库\nimport java.util.Optional;\n\n// ❌ 不要使用通配符导入\nimport java.util.*; // 隐式依赖,合并冲突风险\n\n// ❌ 不要导入未使用的类\nimport java.io.File; // unused → 删除\n```",
|
|
22
|
+
"pattern": "// ✅ 按功能分包 (Feature-based, 推荐)\ncom.example.app\n├── user/\n│ ├── UserController.java\n│ ├── UserService.java\n│ ├── UserRepository.java\n│ └── UserDto.java\n├── order/\n│ ├── OrderController.java\n│ └── OrderService.java\n└── common/\n ├── exception/\n └── config/\n\n// ❌ 按层分包 (Layer-based, 不推荐)\ncom.example.app\n├── controller/ // 所有 controller 混在一起\n├── service/\n├── repository/\n└── dto/\n\n// ✅ 导入规范 (Google Java Style §3.3)\nimport com.example.app.user.User; // 具体类导入\nimport java.util.List; // 标准库\nimport java.util.Optional;\n\n// ❌ 不要使用通配符导入\nimport java.util.*; // 隐式依赖,合并冲突风险\n\n// ❌ 不要导入未使用的类\nimport java.io.File; // unused → 删除",
|
|
23
|
+
"rationale": "按功能分包提高内聚性,便于模块化拆分和团队协作"
|
|
24
|
+
},
|
|
25
|
+
"description": "Java: 按功能分包 + 导入规范",
|
|
26
|
+
"kind": "fact",
|
|
27
|
+
"doClause": "Apply the Java pattern as described",
|
|
28
|
+
"language": "java",
|
|
29
|
+
"headers": [],
|
|
30
|
+
"category": "Tool",
|
|
31
|
+
"knowledgeType": "architecture",
|
|
32
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 按功能分包 + 导入规范的标准实现模式。",
|
|
33
|
+
"scope": "universal",
|
|
34
|
+
"antiPattern": {
|
|
35
|
+
"bad": "import java.util.*; // 通配符导入",
|
|
36
|
+
"why": "隐式依赖,IDE 重构时丢失引用;合并冲突难解决",
|
|
37
|
+
"fix": "逐个导入需要的类:import java.util.List;"
|
|
38
|
+
},
|
|
39
|
+
"reasoning": {
|
|
40
|
+
"whyStandard": "Clean Architecture + Google Java Style Guide §3.3",
|
|
41
|
+
"sources": [
|
|
42
|
+
"Clean Architecture",
|
|
43
|
+
"Google Java Style Guide §3.3"
|
|
44
|
+
],
|
|
45
|
+
"confidence": 0.9
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. 命名约定
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"title": "Java: Google Java Style 命名约定",
|
|
57
|
+
"content": {
|
|
58
|
+
"markdown": "## Java: Google Java Style 命名约定\n\n### 标准模式\n```java\n// ✅ 类名: UpperCamelCase\npublic class UserService { }\npublic interface UserRepository { }\npublic enum OrderStatus { PENDING, CONFIRMED, SHIPPED }\n\n// ✅ 方法/变量: lowerCamelCase\npublic User findUserById(long userId) { ... }\nint maxRetryCount = 3;\n\n// ✅ 常量: UPPER_SNAKE_CASE (static final 不可变)\npublic static final int MAX_CONNECTIONS = 100;\npublic static final String DEFAULT_CHARSET = \"UTF-8\";\n\n// ✅ 包名: 全小写,无下划线\npackage com.example.userservice;\n\n// ✅ 泛型参数: 单大写字母或有意义名称 + T\npublic class Response<T> { }\npublic interface Converter<InputT, OutputT> { }\n\n// ✅ 测试方法: 可用下划线增强可读性\nvoid givenInvalidInput_whenValidate_thenThrows() { }\n```",
|
|
59
|
+
"pattern": "// ✅ 类名: UpperCamelCase\npublic class UserService { }\npublic interface UserRepository { }\npublic enum OrderStatus { PENDING, CONFIRMED, SHIPPED }\n\n// ✅ 方法/变量: lowerCamelCase\npublic User findUserById(long userId) { ... }\nint maxRetryCount = 3;\n\n// ✅ 常量: UPPER_SNAKE_CASE (static final 不可变)\npublic static final int MAX_CONNECTIONS = 100;\npublic static final String DEFAULT_CHARSET = \"UTF-8\";\n\n// ✅ 包名: 全小写,无下划线\npackage com.example.userservice;\n\n// ✅ 泛型参数: 单大写字母或有意义名称 + T\npublic class Response<T> { }\npublic interface Converter<InputT, OutputT> { }\n\n// ✅ 测试方法: 可用下划线增强可读性\nvoid givenInvalidInput_whenValidate_thenThrows() { }",
|
|
60
|
+
"rationale": "统一的命名约定降低团队认知负担,提升代码可预测性"
|
|
61
|
+
},
|
|
62
|
+
"description": "Java: Google Java Style 命名约定",
|
|
63
|
+
"kind": "rule",
|
|
64
|
+
"doClause": "Apply the Java pattern as described",
|
|
65
|
+
"language": "java",
|
|
66
|
+
"headers": [],
|
|
67
|
+
"knowledgeType": "code-standard",
|
|
68
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Google Java Style 命名约定的标准实现模式。",
|
|
69
|
+
"reasoning": {
|
|
70
|
+
"whyStandard": "Google Java Style Guide §5",
|
|
71
|
+
"sources": [
|
|
72
|
+
"Google Java Style Guide §5"
|
|
73
|
+
],
|
|
74
|
+
"confidence": 0.95
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 命名速查表
|
|
80
|
+
|
|
81
|
+
| 标识符类型 | 风格 | 示例 |
|
|
82
|
+
|-----------|------|------|
|
|
83
|
+
| 类/接口/枚举 | `UpperCamelCase` | `UserService`, `Runnable` |
|
|
84
|
+
| 方法 | `lowerCamelCase` | `findUserById()` |
|
|
85
|
+
| 局部变量/参数 | `lowerCamelCase` | `maxRetryCount` |
|
|
86
|
+
| 常量 (`static final`) | `UPPER_SNAKE_CASE` | `MAX_CONNECTIONS` |
|
|
87
|
+
| 包 | 全小写 | `com.example.userservice` |
|
|
88
|
+
| 泛型参数 | 单字母或 `XxxT` | `T`, `InputT` |
|
|
89
|
+
| 枚举值 | `UPPER_SNAKE_CASE` | `PENDING`, `CONFIRMED` |
|
|
90
|
+
|
|
91
|
+
### 命名反模式
|
|
92
|
+
|
|
93
|
+
| 反模式 | 问题 | 修正 |
|
|
94
|
+
|--------|------|------|
|
|
95
|
+
| `IUserService` (I 前缀) | 非 Java 约定(C# 风格) | `UserService` |
|
|
96
|
+
| `UserServiceImpl` (唯一实现) | 无意义后缀 | `DefaultUserService` 或直接 `UserService` |
|
|
97
|
+
| `userDTO` (缩写大小写不一致) | Google Style: 缩写视为普通词 | `UserDto` |
|
|
98
|
+
| `m_field` / `s_field` | 匈牙利标记 | 直接 `field` |
|
|
99
|
+
| `getData()` 返回 void | 方法名暗示返回值 | `loadData()` 或 `fetchData()` |
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 3. 接口与抽象类
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"title": "Java: 面向接口编程 + sealed interface (17+)",
|
|
108
|
+
"content": {
|
|
109
|
+
"markdown": "## Java: 面向接口编程 + sealed interface (17+)\n\n### 标准模式\n```java\n// ✅ 定义接口约定行为\npublic interface UserRepository {\n Optional<User> findById(long id);\n List<User> findByName(String name);\n User save(User user);\n void deleteById(long id);\n}\n\n// ✅ 实现类命名: 按实现方式而非 Impl 后缀\npublic class JpaUserRepository implements UserRepository {\n @Override\n public Optional<User> findById(long id) { ... }\n}\n\n// ✅ 使用接口类型声明依赖\n@Service\npublic class UserService {\n private final UserRepository userRepository;\n\n public UserService(UserRepository userRepository) {\n this.userRepository = userRepository;\n }\n}\n\n// ✅ sealed interface (Java 17+) — 受限实现\npublic sealed interface Shape\n permits Circle, Rectangle, Triangle {\n double area();\n}\n\npublic record Circle(double radius) implements Shape {\n @Override public double area() { return Math.PI * radius * radius; }\n}\n\n// ✅ pattern matching (Java 21+)\ndouble area = switch (shape) {\n case Circle c -> Math.PI * c.radius() * c.radius();\n case Rectangle r -> r.width() * r.height();\n case Triangle t -> 0.5 * t.base() * t.height();\n};\n```",
|
|
110
|
+
"pattern": "// ✅ 定义接口约定行为\npublic interface UserRepository {\n Optional<User> findById(long id);\n List<User> findByName(String name);\n User save(User user);\n void deleteById(long id);\n}\n\n// ✅ 实现类命名: 按实现方式而非 Impl 后缀\npublic class JpaUserRepository implements UserRepository {\n @Override\n public Optional<User> findById(long id) { ... }\n}\n\n// ✅ 使用接口类型声明依赖\n@Service\npublic class UserService {\n private final UserRepository userRepository;\n\n public UserService(UserRepository userRepository) {\n this.userRepository = userRepository;\n }\n}\n\n// ✅ sealed interface (Java 17+) — 受限实现\npublic sealed interface Shape\n permits Circle, Rectangle, Triangle {\n double area();\n}\n\npublic record Circle(double radius) implements Shape {\n @Override public double area() { return Math.PI * radius * radius; }\n}\n\n// ✅ pattern matching (Java 21+)\ndouble area = switch (shape) {\n case Circle c -> Math.PI * c.radius() * c.radius();\n case Rectangle r -> r.width() * r.height();\n case Triangle t -> 0.5 * t.base() * t.height();\n};",
|
|
111
|
+
"rationale": "Java: 面向接口编程 + sealed interface (17+)的标准实现模式。"
|
|
112
|
+
},
|
|
113
|
+
"description": "Java: 面向接口编程 + sealed interface (17+)",
|
|
114
|
+
"kind": "pattern",
|
|
115
|
+
"doClause": "Apply the Java pattern as described",
|
|
116
|
+
"language": "java",
|
|
117
|
+
"headers": [],
|
|
118
|
+
"knowledgeType": "code-pattern",
|
|
119
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 面向接口编程 + sealed interface (17+)的标准实现模式。",
|
|
120
|
+
"antiPattern": {
|
|
121
|
+
"bad": "public class UserServiceImpl implements UserService { }",
|
|
122
|
+
"why": "如果只有一个实现,接口可能不必要;Impl 后缀不提供语义",
|
|
123
|
+
"fix": "按具体实现命名: JpaUserRepository, InMemoryUserRepository"
|
|
124
|
+
},
|
|
125
|
+
"reasoning": {
|
|
126
|
+
"whyStandard": "Effective Java Item 20: Prefer interfaces to abstract classes",
|
|
127
|
+
"sources": [
|
|
128
|
+
"Effective Java §20",
|
|
129
|
+
"JEP 409 (Sealed Classes)"
|
|
130
|
+
],
|
|
131
|
+
"confidence": 0.9
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 4. 异常处理
|
|
139
|
+
|
|
140
|
+
```json
|
|
141
|
+
{
|
|
142
|
+
"title": "Java: 异常处理最佳实践",
|
|
143
|
+
"content": {
|
|
144
|
+
"markdown": "## Java: 异常处理最佳实践\n\n### 标准模式\n```java\n// ✅ 自定义异常体系 — unchecked (RuntimeException)\npublic abstract class AppException extends RuntimeException {\n private final String errorCode;\n protected AppException(String message, String errorCode) {\n super(message);\n this.errorCode = errorCode;\n }\n protected AppException(String message, String errorCode, Throwable cause) {\n super(message, cause);\n this.errorCode = errorCode;\n }\n public String getErrorCode() { return errorCode; }\n}\n\npublic class NotFoundException extends AppException {\n public NotFoundException(String resource, Object id) {\n super(resource + \" not found: \" + id, \"NOT_FOUND\");\n }\n}\n\n// ✅ 精确捕获 + 异常链\ntry {\n User user = userRepository.findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n} catch (NotFoundException e) {\n throw e; // 不要吞掉业务异常\n} catch (DataAccessException e) {\n log.error(\"Database error for user {}\", id, e);\n throw new ServiceException(\"Internal error\", \"DB_ERROR\", e); // 保留 cause\n}\n\n// ✅ try-with-resources\ntry (var conn = dataSource.getConnection();\n var stmt = conn.prepareStatement(sql)) {\n return stmt.executeQuery();\n}\n\n// ✅ 多异常捕获 (Java 7+)\ncatch (IOException | SQLException e) {\n throw new ServiceException(\"IO/DB failure\", e);\n}\n```",
|
|
145
|
+
"pattern": "// ✅ 自定义异常体系 — unchecked (RuntimeException)\npublic abstract class AppException extends RuntimeException {\n private final String errorCode;\n protected AppException(String message, String errorCode) {\n super(message);\n this.errorCode = errorCode;\n }\n protected AppException(String message, String errorCode, Throwable cause) {\n super(message, cause);\n this.errorCode = errorCode;\n }\n public String getErrorCode() { return errorCode; }\n}\n\npublic class NotFoundException extends AppException {\n public NotFoundException(String resource, Object id) {\n super(resource + \" not found: \" + id, \"NOT_FOUND\");\n }\n}\n\n// ✅ 精确捕获 + 异常链\ntry {\n User user = userRepository.findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n} catch (NotFoundException e) {\n throw e; // 不要吞掉业务异常\n} catch (DataAccessException e) {\n log.error(\"Database error for user {}\", id, e);\n throw new ServiceException(\"Internal error\", \"DB_ERROR\", e); // 保留 cause\n}\n\n// ✅ try-with-resources\ntry (var conn = dataSource.getConnection();\n var stmt = conn.prepareStatement(sql)) {\n return stmt.executeQuery();\n}\n\n// ✅ 多异常捕获 (Java 7+)\ncatch (IOException | SQLException e) {\n throw new ServiceException(\"IO/DB failure\", e);\n}",
|
|
146
|
+
"rationale": "Java: 异常处理最佳实践的标准实现模式。"
|
|
147
|
+
},
|
|
148
|
+
"description": "Java: 异常处理最佳实践",
|
|
149
|
+
"kind": "pattern",
|
|
150
|
+
"doClause": "Apply the Java pattern as described",
|
|
151
|
+
"language": "java",
|
|
152
|
+
"headers": [],
|
|
153
|
+
"knowledgeType": "best-practice",
|
|
154
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 异常处理最佳实践的标准实现模式。",
|
|
155
|
+
"antiPattern": {
|
|
156
|
+
"bad": "catch (Exception e) { log.error(e); return null; }",
|
|
157
|
+
"why": "吞掉异常并返回 null → 下游 NPE,难以追踪根因",
|
|
158
|
+
"fix": "精确捕获,保留异常链传播上层"
|
|
159
|
+
},
|
|
160
|
+
"reasoning": {
|
|
161
|
+
"whyStandard": "Effective Java §69-77; Google Java Style Guide §6.2",
|
|
162
|
+
"sources": [
|
|
163
|
+
"Effective Java §69-77",
|
|
164
|
+
"Google Java Style Guide"
|
|
165
|
+
],
|
|
166
|
+
"confidence": 0.95
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 异常处理反模式
|
|
172
|
+
|
|
173
|
+
| 反模式 | 问题 | 修正 |
|
|
174
|
+
|--------|------|------|
|
|
175
|
+
| `catch (Exception e) {}` | 空 catch 吞掉所有错误 | 至少 log 或 rethrow |
|
|
176
|
+
| `catch (Throwable t)` | 捕获 Error (OOM 等) | `catch (Exception e)` |
|
|
177
|
+
| `throws Exception` | 调用方无法精确处理 | 声明具体异常类型 |
|
|
178
|
+
| 异常做流程控制 | 性能差,语义不清 | 用条件判断替代 |
|
|
179
|
+
| `e.printStackTrace()` | 生产环境日志不规范 | `log.error("msg", e)` |
|
|
180
|
+
| 每层重新包装 | 异常链过深 | 只在层边界转换异常类型 |
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## 5. 注解与依赖注入
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"title": "Java: 构造函数注入 > 字段注入",
|
|
189
|
+
"content": {
|
|
190
|
+
"markdown": "## Java: 构造函数注入 > 字段注入\n\n### 标准模式\n```java\n// ✅ 构造函数注入(推荐,不可变依赖)\n@Service\npublic class OrderService {\n private final UserRepository userRepo;\n private final PaymentGateway gateway;\n\n // Spring 4.3+: 单构造函数可省略 @Autowired\n public OrderService(UserRepository userRepo, PaymentGateway gateway) {\n this.userRepo = Objects.requireNonNull(userRepo);\n this.gateway = Objects.requireNonNull(gateway);\n }\n}\n\n// ✅ Lombok 简化(团队统一使用时)\n@Service\n@RequiredArgsConstructor\npublic class OrderService {\n private final UserRepository userRepo;\n private final PaymentGateway gateway;\n}\n\n// ❌ 字段注入(不推荐)\n@Service\npublic class OrderService {\n @Autowired\n private UserRepository userRepo; // 不可测试、隐式依赖、反射注入\n}\n\n// ✅ 自定义注解组合\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Service\n@Transactional(readOnly = true)\npublic @interface ReadOnlyService { }\n```",
|
|
191
|
+
"pattern": "// ✅ 构造函数注入(推荐,不可变依赖)\n@Service\npublic class OrderService {\n private final UserRepository userRepo;\n private final PaymentGateway gateway;\n\n // Spring 4.3+: 单构造函数可省略 @Autowired\n public OrderService(UserRepository userRepo, PaymentGateway gateway) {\n this.userRepo = Objects.requireNonNull(userRepo);\n this.gateway = Objects.requireNonNull(gateway);\n }\n}\n\n// ✅ Lombok 简化(团队统一使用时)\n@Service\n@RequiredArgsConstructor\npublic class OrderService {\n private final UserRepository userRepo;\n private final PaymentGateway gateway;\n}\n\n// ❌ 字段注入(不推荐)\n@Service\npublic class OrderService {\n @Autowired\n private UserRepository userRepo; // 不可测试、隐式依赖、反射注入\n}\n\n// ✅ 自定义注解组合\n@Target(ElementType.TYPE)\n@Retention(RetentionPolicy.RUNTIME)\n@Service\n@Transactional(readOnly = true)\npublic @interface ReadOnlyService { }",
|
|
192
|
+
"rationale": "Java: 构造函数注入 > 字段注入的标准实现模式。"
|
|
193
|
+
},
|
|
194
|
+
"description": "Java: 构造函数注入 > 字段注入",
|
|
195
|
+
"kind": "pattern",
|
|
196
|
+
"doClause": "Apply the Java pattern as described",
|
|
197
|
+
"language": "java",
|
|
198
|
+
"headers": [],
|
|
199
|
+
"knowledgeType": "best-practice",
|
|
200
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 构造函数注入 > 字段注入的标准实现模式。",
|
|
201
|
+
"antiPattern": {
|
|
202
|
+
"bad": "@Autowired private UserRepository userRepo;",
|
|
203
|
+
"why": "字段注入: 无法 final、难以单元测试、隐藏依赖数量",
|
|
204
|
+
"fix": "构造函数注入 + final 字段"
|
|
205
|
+
},
|
|
206
|
+
"reasoning": {
|
|
207
|
+
"whyStandard": "Spring 官方文档推荐构造函数注入; Effective Java §17",
|
|
208
|
+
"sources": [
|
|
209
|
+
"Spring Docs - DI",
|
|
210
|
+
"Effective Java §17"
|
|
211
|
+
],
|
|
212
|
+
"confidence": 0.95
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 6. 泛型 (Generics)
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
{
|
|
223
|
+
"title": "Java: 泛型最佳实践",
|
|
224
|
+
"content": {
|
|
225
|
+
"markdown": "## Java: 泛型最佳实践\n\n### 标准模式\n```java\n// ✅ 类型安全的泛型方法\npublic <T extends Comparable<T>> T max(Collection<T> items) {\n return items.stream()\n .max(Comparator.naturalOrder())\n .orElseThrow();\n}\n\n// ✅ 通配符: PECS (Producer Extends, Consumer Super)\npublic <T> void copy(\n List<? extends T> src, // producer → extends\n List<? super T> dest // consumer → super\n) {\n for (T item : src) {\n dest.add(item);\n }\n}\n\n// ✅ 泛型接口 + 约束\npublic interface Repository<T, ID extends Serializable> {\n Optional<T> findById(ID id);\n T save(T entity);\n void deleteById(ID id);\n}\n\npublic class UserRepository implements Repository<User, Long> {\n @Override\n public Optional<User> findById(Long id) { ... }\n}\n\n// ❌ 不要使用原始类型\nList list = new ArrayList(); // raw type\nList<Object> list = new ArrayList<>(); // 至少用 Object\n\n// ❌ 不要对泛型参数用 instanceof\nif (item instanceof T) { } // 编译错误,类型擦除\n```",
|
|
226
|
+
"pattern": "// ✅ 类型安全的泛型方法\npublic <T extends Comparable<T>> T max(Collection<T> items) {\n return items.stream()\n .max(Comparator.naturalOrder())\n .orElseThrow();\n}\n\n// ✅ 通配符: PECS (Producer Extends, Consumer Super)\npublic <T> void copy(\n List<? extends T> src, // producer → extends\n List<? super T> dest // consumer → super\n) {\n for (T item : src) {\n dest.add(item);\n }\n}\n\n// ✅ 泛型接口 + 约束\npublic interface Repository<T, ID extends Serializable> {\n Optional<T> findById(ID id);\n T save(T entity);\n void deleteById(ID id);\n}\n\npublic class UserRepository implements Repository<User, Long> {\n @Override\n public Optional<User> findById(Long id) { ... }\n}\n\n// ❌ 不要使用原始类型\nList list = new ArrayList(); // raw type\nList<Object> list = new ArrayList<>(); // 至少用 Object\n\n// ❌ 不要对泛型参数用 instanceof\nif (item instanceof T) { } // 编译错误,类型擦除",
|
|
227
|
+
"rationale": "泛型在编译期保证类型安全,PECS 原则最大化灵活性"
|
|
228
|
+
},
|
|
229
|
+
"description": "Java: 泛型最佳实践",
|
|
230
|
+
"kind": "pattern",
|
|
231
|
+
"doClause": "Apply the Java pattern as described",
|
|
232
|
+
"language": "java",
|
|
233
|
+
"headers": [],
|
|
234
|
+
"knowledgeType": "code-pattern",
|
|
235
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 泛型最佳实践的标准实现模式。",
|
|
236
|
+
"reasoning": {
|
|
237
|
+
"whyStandard": "Effective Java §26-33: 优先使用泛型和通配符",
|
|
238
|
+
"sources": [
|
|
239
|
+
"Effective Java §26-33"
|
|
240
|
+
],
|
|
241
|
+
"confidence": 0.9
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 7. Optional
|
|
249
|
+
|
|
250
|
+
```json
|
|
251
|
+
{
|
|
252
|
+
"title": "Java: Optional 正确使用 (Effective Java §55)",
|
|
253
|
+
"content": {
|
|
254
|
+
"markdown": "## Java: Optional 正确使用 (Effective Java §55)\n\n### 标准模式\n```java\n// ✅ Optional 作为返回值 — 表示可能缺失\npublic Optional<User> findByEmail(String email) {\n return Optional.ofNullable(userMap.get(email));\n}\n\n// ✅ 链式处理\nString displayName = findByEmail(email)\n .map(User::getDisplayName)\n .orElse(\"Anonymous\");\n\n// ✅ orElseThrow 替代 get()\nUser user = findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n\n// ✅ Java 9+ ifPresentOrElse\nfindByEmail(email).ifPresentOrElse(\n user -> sendEmail(user),\n () -> log.warn(\"User not found: {}\", email)\n);\n\n// ✅ Stream 集成 (Java 9+)\nList<User> admins = userIds.stream()\n .map(this::findById)\n .flatMap(Optional::stream) // 过滤空值\n .toList();\n\n// ❌ 不要做\nOptional<User> user = ...;\nif (user.isPresent()) { user.get(); } // 等于没用 Optional\n\n// ❌ Optional 作为字段或参数\nprivate Optional<String> name; // 用 @Nullable String\npublic void setName(Optional<String> n); // 直接 String\n```",
|
|
255
|
+
"pattern": "// ✅ Optional 作为返回值 — 表示可能缺失\npublic Optional<User> findByEmail(String email) {\n return Optional.ofNullable(userMap.get(email));\n}\n\n// ✅ 链式处理\nString displayName = findByEmail(email)\n .map(User::getDisplayName)\n .orElse(\"Anonymous\");\n\n// ✅ orElseThrow 替代 get()\nUser user = findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n\n// ✅ Java 9+ ifPresentOrElse\nfindByEmail(email).ifPresentOrElse(\n user -> sendEmail(user),\n () -> log.warn(\"User not found: {}\", email)\n);\n\n// ✅ Stream 集成 (Java 9+)\nList<User> admins = userIds.stream()\n .map(this::findById)\n .flatMap(Optional::stream) // 过滤空值\n .toList();\n\n// ❌ 不要做\nOptional<User> user = ...;\nif (user.isPresent()) { user.get(); } // 等于没用 Optional\n\n// ❌ Optional 作为字段或参数\nprivate Optional<String> name; // 用 @Nullable String\npublic void setName(Optional<String> n); // 直接 String",
|
|
256
|
+
"rationale": "Java: Optional 正确使用 (Effective Java §55)的标准实现模式。"
|
|
257
|
+
},
|
|
258
|
+
"description": "Java: Optional 正确使用 (Effective Java §55)",
|
|
259
|
+
"kind": "pattern",
|
|
260
|
+
"doClause": "Apply the Java pattern as described",
|
|
261
|
+
"language": "java",
|
|
262
|
+
"headers": [],
|
|
263
|
+
"knowledgeType": "best-practice",
|
|
264
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Optional 正确使用 (Effective Java §55)的标准实现模式。",
|
|
265
|
+
"antiPattern": {
|
|
266
|
+
"bad": "if (optional.isPresent()) { return optional.get(); }",
|
|
267
|
+
"why": "Optional 的意义是函数式处理缺失值,isPresent+get 等于回到 null 检查",
|
|
268
|
+
"fix": "optional.map(...).orElse(...) 或 orElseThrow()"
|
|
269
|
+
},
|
|
270
|
+
"reasoning": {
|
|
271
|
+
"whyStandard": "Effective Java §55: Return optionals judiciously",
|
|
272
|
+
"sources": [
|
|
273
|
+
"Effective Java §55"
|
|
274
|
+
],
|
|
275
|
+
"confidence": 0.95
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 8. Stream API
|
|
283
|
+
|
|
284
|
+
```json
|
|
285
|
+
{
|
|
286
|
+
"title": "Java: Stream API 最佳实践",
|
|
287
|
+
"content": {
|
|
288
|
+
"markdown": "## Java: Stream API 最佳实践\n\n### 标准模式\n```java\n// ✅ 简洁的 Stream 管道\nList<String> activeUserNames = users.stream()\n .filter(User::isActive)\n .map(User::getName)\n .sorted()\n .toList(); // Java 16+\n\n// ✅ Collectors 常用模式\nMap<Role, List<User>> byRole = users.stream()\n .collect(Collectors.groupingBy(User::getRole));\n\nString csv = names.stream()\n .collect(Collectors.joining(\", \"));\n\n// ✅ 方法引用优先于 lambda\n.map(User::getName) // ✅ 方法引用\n.map(u -> u.getName()) // ❌ 等价但冗余\n\n// ✅ 大数据集使用 parallelStream(谨慎)\nlong count = hugeList.parallelStream()\n .filter(this::isExpensive)\n .count();\n\n// ❌ 避免过长链(>5 步拆分)\n// ❌ 避免 Stream 中的副作用\nusers.stream().forEach(u -> u.setActive(true)); // 副作用 → 用 for 循环\n\n// ❌ 不要重用 Stream\nStream<User> s = users.stream();\ns.count(); s.toList(); // IllegalStateException!\n```",
|
|
289
|
+
"pattern": "// ✅ 简洁的 Stream 管道\nList<String> activeUserNames = users.stream()\n .filter(User::isActive)\n .map(User::getName)\n .sorted()\n .toList(); // Java 16+\n\n// ✅ Collectors 常用模式\nMap<Role, List<User>> byRole = users.stream()\n .collect(Collectors.groupingBy(User::getRole));\n\nString csv = names.stream()\n .collect(Collectors.joining(\", \"));\n\n// ✅ 方法引用优先于 lambda\n.map(User::getName) // ✅ 方法引用\n.map(u -> u.getName()) // ❌ 等价但冗余\n\n// ✅ 大数据集使用 parallelStream(谨慎)\nlong count = hugeList.parallelStream()\n .filter(this::isExpensive)\n .count();\n\n// ❌ 避免过长链(>5 步拆分)\n// ❌ 避免 Stream 中的副作用\nusers.stream().forEach(u -> u.setActive(true)); // 副作用 → 用 for 循环\n\n// ❌ 不要重用 Stream\nStream<User> s = users.stream();\ns.count(); s.toList(); // IllegalStateException!",
|
|
290
|
+
"rationale": "Java: Stream API 最佳实践的标准实现模式。"
|
|
291
|
+
},
|
|
292
|
+
"description": "Java: Stream API 最佳实践",
|
|
293
|
+
"kind": "pattern",
|
|
294
|
+
"doClause": "Apply the Java pattern as described",
|
|
295
|
+
"language": "java",
|
|
296
|
+
"headers": [],
|
|
297
|
+
"knowledgeType": "code-pattern",
|
|
298
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Stream API 最佳实践的标准实现模式。",
|
|
299
|
+
"antiPattern": {
|
|
300
|
+
"bad": "users.stream().forEach(u -> u.setActive(true));",
|
|
301
|
+
"why": "Stream forEach 中的副作用破坏函数式语义,parallelStream 下更危险",
|
|
302
|
+
"fix": "副作用操作使用传统 for 循环"
|
|
303
|
+
},
|
|
304
|
+
"reasoning": {
|
|
305
|
+
"whyStandard": "Effective Java §45-48: 谨慎使用 Stream",
|
|
306
|
+
"sources": [
|
|
307
|
+
"Effective Java §45-48"
|
|
308
|
+
],
|
|
309
|
+
"confidence": 0.9
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 9. Record 与不可变性 (Java 16+)
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{
|
|
320
|
+
"title": "Java: Record + 不可变设计",
|
|
321
|
+
"content": {
|
|
322
|
+
"markdown": "## Java: Record + 不可变设计\n\n### 标准模式\n```java\n// ✅ Record — 不可变数据载体,自动生成 equals/hashCode/toString\npublic record UserDto(\n long id,\n String name,\n String email,\n Instant createdAt\n) {\n // 紧凑构造函数进行校验\n public UserDto {\n Objects.requireNonNull(name, \"name must not be null\");\n Objects.requireNonNull(email, \"email must not be null\");\n }\n}\n\n// ✅ 泛型 Record\npublic record ApiResponse<T>(boolean success, T data, String message) {\n public static <T> ApiResponse<T> ok(T data) {\n return new ApiResponse<>(true, data, null);\n }\n public static ApiResponse<Void> error(String msg) {\n return new ApiResponse<>(false, null, msg);\n }\n}\n\n// ✅ 不可变类设计 (Effective Java §17)\npublic final class Money {\n private final BigDecimal amount;\n private final Currency currency;\n\n public Money(BigDecimal amount, Currency currency) {\n this.amount = Objects.requireNonNull(amount);\n this.currency = Objects.requireNonNull(currency);\n }\n\n // 返回新实例而非修改状态\n public Money add(Money other) {\n if (!this.currency.equals(other.currency))\n throw new IllegalArgumentException(\"Currency mismatch\");\n return new Money(this.amount.add(other.amount), this.currency);\n }\n\n // 防御性拷贝集合\n public List<String> getTags() {\n return List.copyOf(tags); // 不可变副本\n }\n}\n```",
|
|
323
|
+
"pattern": "// ✅ Record — 不可变数据载体,自动生成 equals/hashCode/toString\npublic record UserDto(\n long id,\n String name,\n String email,\n Instant createdAt\n) {\n // 紧凑构造函数进行校验\n public UserDto {\n Objects.requireNonNull(name, \"name must not be null\");\n Objects.requireNonNull(email, \"email must not be null\");\n }\n}\n\n// ✅ 泛型 Record\npublic record ApiResponse<T>(boolean success, T data, String message) {\n public static <T> ApiResponse<T> ok(T data) {\n return new ApiResponse<>(true, data, null);\n }\n public static ApiResponse<Void> error(String msg) {\n return new ApiResponse<>(false, null, msg);\n }\n}\n\n// ✅ 不可变类设计 (Effective Java §17)\npublic final class Money {\n private final BigDecimal amount;\n private final Currency currency;\n\n public Money(BigDecimal amount, Currency currency) {\n this.amount = Objects.requireNonNull(amount);\n this.currency = Objects.requireNonNull(currency);\n }\n\n // 返回新实例而非修改状态\n public Money add(Money other) {\n if (!this.currency.equals(other.currency))\n throw new IllegalArgumentException(\"Currency mismatch\");\n return new Money(this.amount.add(other.amount), this.currency);\n }\n\n // 防御性拷贝集合\n public List<String> getTags() {\n return List.copyOf(tags); // 不可变副本\n }\n}",
|
|
324
|
+
"rationale": "不可变对象线程安全、可安全共享、易于推理"
|
|
325
|
+
},
|
|
326
|
+
"description": "Java: Record + 不可变设计",
|
|
327
|
+
"kind": "pattern",
|
|
328
|
+
"doClause": "Apply the Java pattern as described",
|
|
329
|
+
"language": "java",
|
|
330
|
+
"headers": [],
|
|
331
|
+
"knowledgeType": "code-pattern",
|
|
332
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Record + 不可变设计的标准实现模式。",
|
|
333
|
+
"reasoning": {
|
|
334
|
+
"whyStandard": "Effective Java §17: Minimize mutability; JEP 395 (Records)",
|
|
335
|
+
"sources": [
|
|
336
|
+
"Effective Java §17",
|
|
337
|
+
"JEP 395"
|
|
338
|
+
],
|
|
339
|
+
"confidence": 0.9
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## 10. 并发与虚拟线程
|
|
347
|
+
|
|
348
|
+
```json
|
|
349
|
+
{
|
|
350
|
+
"title": "Java: 现代并发模式",
|
|
351
|
+
"content": {
|
|
352
|
+
"markdown": "## Java: 现代并发模式\n\n### 标准模式\n```java\n// ✅ CompletableFuture 异步编排\npublic CompletableFuture<Dashboard> loadDashboard(long userId) {\n var userFuture = CompletableFuture.supplyAsync(\n () -> userService.findById(userId), executor);\n var ordersFuture = CompletableFuture.supplyAsync(\n () -> orderService.findByUser(userId), executor);\n\n return userFuture.thenCombine(ordersFuture, Dashboard::new)\n .exceptionally(ex -> {\n log.error(\"Dashboard load failed\", ex);\n return Dashboard.empty();\n });\n}\n\n// ✅ 虚拟线程 (Java 21+, Project Loom)\ntry (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n List<Future<User>> futures = userIds.stream()\n .map(id -> executor.submit(() -> fetchUser(id)))\n .toList();\n}\n\n// ✅ Structured Concurrency (Java 21 Preview)\ntry (var scope = new StructuredTaskScope.ShutdownOnFailure()) {\n var userTask = scope.fork(() -> findUser(userId));\n var ordersTask = scope.fork(() -> findOrders(userId));\n scope.join().throwIfFailed();\n return new Dashboard(userTask.get(), ordersTask.get());\n}\n\n// ✅ 线程安全的集合\nMap<String, User> cache = new ConcurrentHashMap<>();\nList<Event> events = new CopyOnWriteArrayList<>();\n\n// ❌ 反模式\nsynchronized (this) { ... } // 锁范围过大\nnew Thread(() -> ...).start(); // 未管理线程生命周期\n```",
|
|
353
|
+
"pattern": "// ✅ CompletableFuture 异步编排\npublic CompletableFuture<Dashboard> loadDashboard(long userId) {\n var userFuture = CompletableFuture.supplyAsync(\n () -> userService.findById(userId), executor);\n var ordersFuture = CompletableFuture.supplyAsync(\n () -> orderService.findByUser(userId), executor);\n\n return userFuture.thenCombine(ordersFuture, Dashboard::new)\n .exceptionally(ex -> {\n log.error(\"Dashboard load failed\", ex);\n return Dashboard.empty();\n });\n}\n\n// ✅ 虚拟线程 (Java 21+, Project Loom)\ntry (var executor = Executors.newVirtualThreadPerTaskExecutor()) {\n List<Future<User>> futures = userIds.stream()\n .map(id -> executor.submit(() -> fetchUser(id)))\n .toList();\n}\n\n// ✅ Structured Concurrency (Java 21 Preview)\ntry (var scope = new StructuredTaskScope.ShutdownOnFailure()) {\n var userTask = scope.fork(() -> findUser(userId));\n var ordersTask = scope.fork(() -> findOrders(userId));\n scope.join().throwIfFailed();\n return new Dashboard(userTask.get(), ordersTask.get());\n}\n\n// ✅ 线程安全的集合\nMap<String, User> cache = new ConcurrentHashMap<>();\nList<Event> events = new CopyOnWriteArrayList<>();\n\n// ❌ 反模式\nsynchronized (this) { ... } // 锁范围过大\nnew Thread(() -> ...).start(); // 未管理线程生命周期",
|
|
354
|
+
"rationale": "Java: 现代并发模式的标准实现模式。"
|
|
355
|
+
},
|
|
356
|
+
"description": "Java: 现代并发模式",
|
|
357
|
+
"kind": "pattern",
|
|
358
|
+
"doClause": "Apply the Java pattern as described",
|
|
359
|
+
"language": "java",
|
|
360
|
+
"headers": [],
|
|
361
|
+
"knowledgeType": "best-practice",
|
|
362
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: 现代并发模式的标准实现模式。",
|
|
363
|
+
"reasoning": {
|
|
364
|
+
"whyStandard": "JEP 444 (Virtual Threads), JEP 453 (Structured Concurrency)",
|
|
365
|
+
"sources": [
|
|
366
|
+
"Effective Java §78-84",
|
|
367
|
+
"JEP 444",
|
|
368
|
+
"JEP 453"
|
|
369
|
+
],
|
|
370
|
+
"confidence": 0.85
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## 11. Builder 与工厂模式
|
|
378
|
+
|
|
379
|
+
```json
|
|
380
|
+
{
|
|
381
|
+
"title": "Java: Builder 模式 (Effective Java §2)",
|
|
382
|
+
"content": {
|
|
383
|
+
"markdown": "## Java: Builder 模式 (Effective Java §2)\n\n### 标准模式\n```java\n// ✅ Builder 模式 — 参数多于 4 个时使用\npublic class ServerConfig {\n private final String host;\n private final int port;\n private final int maxConnections;\n private final Duration timeout;\n private final boolean ssl;\n\n private ServerConfig(Builder builder) {\n this.host = builder.host;\n this.port = builder.port;\n this.maxConnections = builder.maxConnections;\n this.timeout = builder.timeout;\n this.ssl = builder.ssl;\n }\n\n public static class Builder {\n // 必填\n private final String host;\n private final int port;\n // 可选 + 默认值\n private int maxConnections = 100;\n private Duration timeout = Duration.ofSeconds(30);\n private boolean ssl = false;\n\n public Builder(String host, int port) {\n this.host = host;\n this.port = port;\n }\n\n public Builder maxConnections(int val) {\n this.maxConnections = val; return this;\n }\n public Builder timeout(Duration val) {\n this.timeout = val; return this;\n }\n public Builder ssl(boolean val) {\n this.ssl = val; return this;\n }\n public ServerConfig build() {\n return new ServerConfig(this);\n }\n }\n}\n\n// ✅ Lombok @Builder 简化\n@Builder\n@Value // 不可变\npublic class ServerConfig {\n String host;\n int port;\n @Builder.Default int maxConnections = 100;\n @Builder.Default Duration timeout = Duration.ofSeconds(30);\n}\n\n// ✅ 静态工厂方法 (Effective Java §1)\npublic static ServerConfig ofLocal(int port) {\n return new Builder(\"localhost\", port).build();\n}\n```",
|
|
384
|
+
"pattern": "// ✅ Builder 模式 — 参数多于 4 个时使用\npublic class ServerConfig {\n private final String host;\n private final int port;\n private final int maxConnections;\n private final Duration timeout;\n private final boolean ssl;\n\n private ServerConfig(Builder builder) {\n this.host = builder.host;\n this.port = builder.port;\n this.maxConnections = builder.maxConnections;\n this.timeout = builder.timeout;\n this.ssl = builder.ssl;\n }\n\n public static class Builder {\n // 必填\n private final String host;\n private final int port;\n // 可选 + 默认值\n private int maxConnections = 100;\n private Duration timeout = Duration.ofSeconds(30);\n private boolean ssl = false;\n\n public Builder(String host, int port) {\n this.host = host;\n this.port = port;\n }\n\n public Builder maxConnections(int val) {\n this.maxConnections = val; return this;\n }\n public Builder timeout(Duration val) {\n this.timeout = val; return this;\n }\n public Builder ssl(boolean val) {\n this.ssl = val; return this;\n }\n public ServerConfig build() {\n return new ServerConfig(this);\n }\n }\n}\n\n// ✅ Lombok @Builder 简化\n@Builder\n@Value // 不可变\npublic class ServerConfig {\n String host;\n int port;\n @Builder.Default int maxConnections = 100;\n @Builder.Default Duration timeout = Duration.ofSeconds(30);\n}\n\n// ✅ 静态工厂方法 (Effective Java §1)\npublic static ServerConfig ofLocal(int port) {\n return new Builder(\"localhost\", port).build();\n}",
|
|
385
|
+
"rationale": "Builder 模式提供流畅、可读的对象构建方式,避免需要多种构造函数重载"
|
|
386
|
+
},
|
|
387
|
+
"description": "Java: Builder 模式 (Effective Java §2)",
|
|
388
|
+
"kind": "pattern",
|
|
389
|
+
"doClause": "Apply the Java pattern as described",
|
|
390
|
+
"language": "java",
|
|
391
|
+
"headers": [],
|
|
392
|
+
"knowledgeType": "code-pattern",
|
|
393
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Builder 模式 (Effective Java §2)的标准实现模式。",
|
|
394
|
+
"reasoning": {
|
|
395
|
+
"whyStandard": "Effective Java §1-2: 静态工厂 + Builder 模式",
|
|
396
|
+
"sources": [
|
|
397
|
+
"Effective Java §1-2"
|
|
398
|
+
],
|
|
399
|
+
"confidence": 0.9
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
## 12. 测试模式
|
|
407
|
+
|
|
408
|
+
```json
|
|
409
|
+
{
|
|
410
|
+
"title": "Java: JUnit 5 + Mockito 测试模式",
|
|
411
|
+
"content": {
|
|
412
|
+
"markdown": "## Java: JUnit 5 + Mockito 测试模式\n\n### 标准模式\n```java\n// ✅ 测试类结构\n@ExtendWith(MockitoExtension.class)\nclass UserServiceTest {\n\n @Mock\n private UserRepository userRepository;\n\n @InjectMocks\n private UserService userService;\n\n // ✅ Given-When-Then 结构\n @Test\n @DisplayName(\"findById - 存在的用户 - 返回 UserDto\")\n void findById_existingUser_returnsDto() {\n // Given\n var user = new User(1L, \"Alice\", \"alice@test.com\");\n when(userRepository.findById(1L)).thenReturn(Optional.of(user));\n\n // When\n var result = userService.findById(1L);\n\n // Then\n assertThat(result)\n .isNotNull()\n .extracting(UserDto::name, UserDto::email)\n .containsExactly(\"Alice\", \"alice@test.com\");\n }\n\n // ✅ 异常测试\n @Test\n void findById_notFound_throwsException() {\n when(userRepository.findById(99L)).thenReturn(Optional.empty());\n\n assertThatThrownBy(() -> userService.findById(99L))\n .isInstanceOf(NotFoundException.class)\n .hasMessageContaining(\"99\");\n }\n\n // ✅ 参数化测试\n @ParameterizedTest\n @CsvSource({\"1,Alice\", \"2,Bob\", \"3,Charlie\"})\n void findById_variousIds_returnsCorrectName(long id, String name) {\n when(userRepository.findById(id))\n .thenReturn(Optional.of(new User(id, name, name + \"@test.com\")));\n assertThat(userService.findById(id).name()).isEqualTo(name);\n }\n}\n```",
|
|
413
|
+
"pattern": "// ✅ 测试类结构\n@ExtendWith(MockitoExtension.class)\nclass UserServiceTest {\n\n @Mock\n private UserRepository userRepository;\n\n @InjectMocks\n private UserService userService;\n\n // ✅ Given-When-Then 结构\n @Test\n @DisplayName(\"findById - 存在的用户 - 返回 UserDto\")\n void findById_existingUser_returnsDto() {\n // Given\n var user = new User(1L, \"Alice\", \"alice@test.com\");\n when(userRepository.findById(1L)).thenReturn(Optional.of(user));\n\n // When\n var result = userService.findById(1L);\n\n // Then\n assertThat(result)\n .isNotNull()\n .extracting(UserDto::name, UserDto::email)\n .containsExactly(\"Alice\", \"alice@test.com\");\n }\n\n // ✅ 异常测试\n @Test\n void findById_notFound_throwsException() {\n when(userRepository.findById(99L)).thenReturn(Optional.empty());\n\n assertThatThrownBy(() -> userService.findById(99L))\n .isInstanceOf(NotFoundException.class)\n .hasMessageContaining(\"99\");\n }\n\n // ✅ 参数化测试\n @ParameterizedTest\n @CsvSource({\"1,Alice\", \"2,Bob\", \"3,Charlie\"})\n void findById_variousIds_returnsCorrectName(long id, String name) {\n when(userRepository.findById(id))\n .thenReturn(Optional.of(new User(id, name, name + \"@test.com\")));\n assertThat(userService.findById(id).name()).isEqualTo(name);\n }\n}",
|
|
414
|
+
"rationale": "Given-When-Then 结构清晰; AssertJ 流式断言可读性高; 参数化减少重复"
|
|
415
|
+
},
|
|
416
|
+
"description": "Java: JUnit 5 + Mockito 测试模式",
|
|
417
|
+
"kind": "pattern",
|
|
418
|
+
"doClause": "Apply the Java pattern as described",
|
|
419
|
+
"language": "java",
|
|
420
|
+
"headers": [],
|
|
421
|
+
"knowledgeType": "best-practice",
|
|
422
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: JUnit 5 + Mockito 测试模式的标准实现模式。",
|
|
423
|
+
"reasoning": {
|
|
424
|
+
"whyStandard": "JUnit 5 Best Practices + Spring Test 官方指南",
|
|
425
|
+
"sources": [
|
|
426
|
+
"JUnit 5 User Guide",
|
|
427
|
+
"Spring Testing Docs"
|
|
428
|
+
],
|
|
429
|
+
"confidence": 0.9
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## 13. 字符串与文本块
|
|
437
|
+
|
|
438
|
+
```json
|
|
439
|
+
{
|
|
440
|
+
"title": "Java: Text Blocks + 字符串处理 (Java 15+)",
|
|
441
|
+
"content": {
|
|
442
|
+
"markdown": "## Java: Text Blocks + 字符串处理 (Java 15+)\n\n### 标准模式\n```java\n// ✅ Text Block — 多行字符串 (Java 15+)\nString json = \"\"\"\n {\n \"name\": \"%s\",\n \"age\": %d\n }\n \"\"\".formatted(name, age);\n\n// ✅ String.formatted() 替代 String.format()\nString msg = \"User %s (id=%d) created\".formatted(name, id);\n\n// ✅ StringBuilder 拼接大量字符串\nvar sb = new StringBuilder(256);\nfor (var item : items) {\n sb.append(item.name()).append(\", \");\n}\n\n// ✅ String.join / Collectors.joining\nString csv = String.join(\", \", names);\nString csv2 = names.stream().collect(Collectors.joining(\", \", \"[\", \"]\"));\n\n// ❌ 循环中用 + 拼接字符串\nString result = \"\";\nfor (var s : list) { result += s; } // O(n²)\n```",
|
|
443
|
+
"pattern": "// ✅ Text Block — 多行字符串 (Java 15+)\nString json = \"\"\"\n {\n \"name\": \"%s\",\n \"age\": %d\n }\n \"\"\".formatted(name, age);\n\n// ✅ String.formatted() 替代 String.format()\nString msg = \"User %s (id=%d) created\".formatted(name, id);\n\n// ✅ StringBuilder 拼接大量字符串\nvar sb = new StringBuilder(256);\nfor (var item : items) {\n sb.append(item.name()).append(\", \");\n}\n\n// ✅ String.join / Collectors.joining\nString csv = String.join(\", \", names);\nString csv2 = names.stream().collect(Collectors.joining(\", \", \"[\", \"]\"));\n\n// ❌ 循环中用 + 拼接字符串\nString result = \"\";\nfor (var s : list) { result += s; } // O(n²)",
|
|
444
|
+
"rationale": "Java: Text Blocks + 字符串处理 (Java 15+)的标准实现模式。"
|
|
445
|
+
},
|
|
446
|
+
"description": "Java: Text Blocks + 字符串处理 (Java 15+)",
|
|
447
|
+
"kind": "pattern",
|
|
448
|
+
"doClause": "Apply the Java pattern as described",
|
|
449
|
+
"language": "java",
|
|
450
|
+
"headers": [],
|
|
451
|
+
"knowledgeType": "code-pattern",
|
|
452
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Text Blocks + 字符串处理 (Java 15+)的标准实现模式。",
|
|
453
|
+
"antiPattern": {
|
|
454
|
+
"bad": "String result = \"\"; for (s : list) result += s;",
|
|
455
|
+
"why": "String 不可变,每次 + 创建新对象,O(n²) 性能",
|
|
456
|
+
"fix": "StringBuilder 或 String.join / Collectors.joining"
|
|
457
|
+
},
|
|
458
|
+
"reasoning": {
|
|
459
|
+
"whyStandard": "JEP 378 (Text Blocks); Effective Java §63",
|
|
460
|
+
"sources": [
|
|
461
|
+
"JEP 378",
|
|
462
|
+
"Effective Java §63"
|
|
463
|
+
],
|
|
464
|
+
"confidence": 0.9
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## 14. Javadoc 规范
|
|
472
|
+
|
|
473
|
+
```json
|
|
474
|
+
{
|
|
475
|
+
"title": "Java: Javadoc 规范 (Google Java Style §7)",
|
|
476
|
+
"content": {
|
|
477
|
+
"markdown": "## Java: Javadoc 规范 (Google Java Style §7)\n\n### 标准模式\n```java\n/**\n * 用户服务,提供用户的 CRUD 操作。\n *\n * <p>所有方法都是线程安全的。使用构造函数注入依赖。\n *\n * @since 2.0\n * @author team-backend\n */\n@Service\npublic class UserService {\n\n /**\n * 按 ID 查找用户。\n *\n * <p>如果用户不存在则抛出 {@link NotFoundException}。\n *\n * @param id 用户的唯一标识符,必须大于 0\n * @return 找到的用户实体,不为 null\n * @throws NotFoundException 如果用户不存在\n * @throws IllegalArgumentException 如果 id <= 0\n */\n public User findById(long id) {\n if (id <= 0) throw new IllegalArgumentException(\"id must be > 0\");\n return userRepository.findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n }\n}\n```",
|
|
478
|
+
"pattern": "/**\n * 用户服务,提供用户的 CRUD 操作。\n *\n * <p>所有方法都是线程安全的。使用构造函数注入依赖。\n *\n * @since 2.0\n * @author team-backend\n */\n@Service\npublic class UserService {\n\n /**\n * 按 ID 查找用户。\n *\n * <p>如果用户不存在则抛出 {@link NotFoundException}。\n *\n * @param id 用户的唯一标识符,必须大于 0\n * @return 找到的用户实体,不为 null\n * @throws NotFoundException 如果用户不存在\n * @throws IllegalArgumentException 如果 id <= 0\n */\n public User findById(long id) {\n if (id <= 0) throw new IllegalArgumentException(\"id must be > 0\");\n return userRepository.findById(id)\n .orElseThrow(() -> new NotFoundException(\"User\", id));\n }\n}",
|
|
479
|
+
"rationale": "Javadoc 是 Java 生态的标准文档方式,@param/@return/@throws 提供完整 API 契约"
|
|
480
|
+
},
|
|
481
|
+
"description": "Java: Javadoc 规范 (Google Java Style §7)",
|
|
482
|
+
"kind": "rule",
|
|
483
|
+
"doClause": "Apply the Java pattern as described",
|
|
484
|
+
"language": "java",
|
|
485
|
+
"headers": [],
|
|
486
|
+
"knowledgeType": "code-standard",
|
|
487
|
+
"usageGuide": "### 使用场景\\n触发 `@trigger` 获取Java: Javadoc 规范 (Google Java Style §7)的标准实现模式。",
|
|
488
|
+
"reasoning": {
|
|
489
|
+
"whyStandard": "Google Java Style Guide §7; 所有 public API 必须有 Javadoc",
|
|
490
|
+
"sources": [
|
|
491
|
+
"Google Java Style Guide §7"
|
|
492
|
+
],
|
|
493
|
+
"confidence": 0.95
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Javadoc 反模式
|
|
499
|
+
|
|
500
|
+
| 反模式 | 问题 | 修正 |
|
|
501
|
+
|--------|------|------|
|
|
502
|
+
| `/** Gets the name. */` | 重复方法名,无额外信息 | 描述行为、边界和异常 |
|
|
503
|
+
| 缺少 `@throws` | 调用方不知道可能的异常 | 列出所有非检查异常 |
|
|
504
|
+
| `@param id id` | 参数解释等于没有 | `@param id 用户唯一标识符,必须大于 0` |
|
|
505
|
+
| private 方法写 Javadoc | 过度文档化 | 代码自解释 + 行内注释 |
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
## 15. Java 特有维度 (extraDimensions)
|
|
510
|
+
|
|
511
|
+
冷启动分析 Java 项目时,除了通用维度,还应额外关注:
|
|
512
|
+
|
|
513
|
+
| 额外维度 | 寻找什么 | 候选类型 |
|
|
514
|
+
|---------|---------|---------|
|
|
515
|
+
| **Java 版本特性** | Record, sealed class, pattern matching, 虚拟线程 | `code-pattern` |
|
|
516
|
+
| **不可变设计** | final class/field, 防御性拷贝, Immutables/Lombok @Value | `best-practice` |
|
|
517
|
+
| **泛型使用** | PECS, 有界通配符, 泛型方法 vs 泛型类 | `code-pattern` |
|
|
518
|
+
| **Optional** | 返回值 Optional, 避免 isPresent+get, stream 集成 | `best-practice` |
|
|
519
|
+
| **并发模式** | CompletableFuture, VirtualThread, ConcurrentHashMap | `code-pattern` |
|
|
520
|
+
| **框架模式** | Spring Boot autoconfiguration, DI, AOP | `architecture` |
|
|
521
|
+
| **构建工具** | Maven/Gradle, 多模块, BOM 依赖管理 | `config` |
|
|
522
|
+
| **测试** | JUnit 5, Mockito, TestContainers, Spring Boot Test | `best-practice` |
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## 关联 Skills
|
|
527
|
+
|
|
528
|
+
- **autosnippet-coldstart**: 冷启动分析模板
|
|
529
|
+
- **autosnippet-reference-kotlin**: Kotlin 业界最佳实践参考
|
|
530
|
+
- **autosnippet-reference-python**: Python 业界最佳实践参考
|
|
531
|
+
- **autosnippet-reference-jsts**: JavaScript/TypeScript 业界最佳实践参考
|
|
532
|
+
- **autosnippet-reference-objc**: Objective-C 业界最佳实践参考
|
|
533
|
+
- **autosnippet-reference-swift**: Swift 业界最佳实践参考
|
|
534
|
+
- **autosnippet-reference-dart**: Dart (Flutter) 业界最佳实践参考
|