用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Objective-Arts/lens --skill java命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | java |
| description | Effective Java patterns |
| allowed-tools | [] |
Josh Bloch's core belief: APIs should be easy to use correctly and hard to use incorrectly. Every design decision should make the right thing easy and the wrong thing difficult or impossible.
"When in doubt, leave it out."
If you're unsure whether a feature, parameter, or method belongs, it probably doesn't. You can always add later. You can never remove without breaking clients.
Immutable objects are simple, thread-safe, and can be shared freely.
Make classes immutable unless there's a good reason not to:
Not this:
public class Period {
private Date start;
private Date end;
public void setStart(Date start) { this.start = start; }
public Date getStart() { return start; } // Leaks mutable reference
}
This:
public final class Period {
private final Date start;
private final Date end;
public Period(Date start, Date end) {
this.start = new Date(start.getTime()); // Defensive copy
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0)
throw new IllegalArgumentException("start after end");
}
public Date getStart() { return new Date(start.getTime()); } // Defensive copy
}
Static factories have names, don't require new object creation, and can return subtypes.
Not this:
Boolean flag = new Boolean(true); // Always creates object
This:
Boolean flag = Boolean.valueOf(true); // Can return cached instance
Name conventions:
from - type conversion: Date.from(instant)of - aggregation: EnumSet.of(JACK, QUEEN, KING)valueOf - verbose alternative to ofgetInstance / instance - returns instance (may be cached)newInstance / create - guarantees new instancegetType / newType - factory in different classInheritance violates encapsulation. The subclass depends on implementation details of the superclass.
Not this:
public class InstrumentedHashSet<E> extends HashSet<E> {
private int addCount = 0;
@Override
public boolean add(E e) {
addCount++;
return super.add(e); // What if HashSet.addAll calls add()?
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c); // Double counting!
}
}
This (composition with forwarding):
public class InstrumentedSet<E> implements Set<E> {
private final Set<E> s;
private int addCount = 0;
public InstrumentedSet(Set<E> s) { this.s = s; }
public boolean add(E e) {
addCount++;
return s.add(e);
}
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return s.addAll(c);
}
// ... delegate all other Set methods to s
}
If you allow inheritance, document precisely what subclasses can rely on. If you don't want to make that commitment, make the class final.
Refer to objects by their interfaces. This allows flexibility to change implementations.
Not this:
LinkedHashSet<String> names = new LinkedHashSet<>();
This:
Set<String> names = new LinkedHashSet<>();
Never force callers to write null checks for collections.
Not this:
public List<Item> getItems() {
if (items.isEmpty()) return null; // Forces null check
return items;
}
This:
public List<Item> getItems() {
return items.isEmpty()
? Collections.emptyList()
: new ArrayList<>(items);
}
Optionals are for return values that might legitimately be absent. Never use for fields, parameters, or collections.
Appropriate:
public Optional<Item> findById(long id) {
return Optional.ofNullable(cache.get(id));
}
Never:
// Don't do any of these
private Optional<Item> item; // Field
public void process(Optional<Item> item) { } // Parameter
public Optional<List<Item>> getItems() { } // Optional of collection
Detect errors as early as possible. Validate parameters at the start of methods.
Not this:
public void process(String input) {
// ... 50 lines of code ...
input.toLowerCase(); // NullPointerException here, far from cause
}
This:
public void process(String input) {
Objects.requireNonNull(input, "input must not be null");
if (input.isEmpty()) {
throw new IllegalArgumentException("input must not be empty");
}
// ... proceed with valid input ...
}
If you override equals, you must override hashCode. Objects that are equal must have equal hash codes.
The equals contract:
x.equals(x) is truex.equals(y) iff y.equals(x)x.equals(y) and y.equals(z), then x.equals(z)x.equals(null) is falseWhen constructors have many parameters (especially optional ones), use the Builder pattern.
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
Before committing any API or class design, ask:
Apply these checks:
Use a different skill when:
simplicity (Go Proverbs, small interfaces)design-patterns (23 patterns catalog)correctness (invariants, weakest preconditions)clarity (readability, naming)optimization (cache behavior, profiling)Bloch is the Java/Kotlin skill—use it for defensive API design and robust object-oriented code.
"APIs should be easy to use correctly and hard to use incorrectly." — Josh Bloch
Audit a project against a canon's rules and checklist. Read-only — produces prioritized report without fixing. Works with any canon (nextjs, sql, typescript, etc.).
Lens home base - status, help, and setup
Plan and build a new feature with quality gates.