skip to content

You see a compile error like 'method set in interface List cannot be applied; required: CAP#1, found: Object'. What does it mean and how do you fix it?

level: seniorimportance: nice to knowfreq 30%

answer

  1. CAP#1 = compiler's name for the wildcard's unknown type
  2. Error: required CAP#1, found Object
  3. Caused by self-write on List<?> (get returns Object)
  4. Fix: route through <T> generic helper
  5. Don't fix with unchecked cast

basics

~20 s

It means you tried to write a plain Object into a list whose element type is an unknown captured wildcard (CAP#1). The compiler can't prove the Object is the right type. Fix it by routing through a generic helper method so the unknown type gets a name.

solid answer

~40 s

The 'CAP#1' (or 'capture of ?') in the message is the fresh type variable the compiler invented for an unbounded or bounded wildcard's unknown type. The error says set expects a value of that captured type, but you handed it an Object — typically because you did list.set(i, list.get(j)) on a List<?>, where get returns Object. The compiler refuses because an arbitrary Object might not be the real element type. The standard fix is the capture-helper idiom: delegate to a private generic method <T> that takes List<T>; passing the wildcard list captures the type as T, after which get returns T and set accepts T, so the round-trip type-checks. Avoid the tempting but unsafe alternative of casting to List<Object> or raw List with @SuppressWarnings.

code

java · 10 lines
java
// Error-producing version
void rotate(List<?> list) {
    list.set(0, list.get(1)); // required: CAP#1, found: Object
}

// Fixed with capture helper
void rotate(List<?> list) { rotateHelper(list); }
private <T> void rotateHelper(List<T> list) {
    list.set(0, list.get(1)); // get -> T, set accepts T: compiles
}

go deeper

for a junior

Recognizes the error mentions wildcards/capture and that something about generics is wrong.

for a middle

Identifies the self-write-on-wildcard cause and knows a generic helper resolves it.

for a senior

Reads the CAP#1 message fluently, applies the capture-helper idiom, and rejects unsafe cast workarounds.

for a principal

Coaches others on diagnosing capture errors, codifies the idiom in guidelines, and recognizes deeper inference/overload-resolution interactions that surface capture in messages.

## Reading the error A message like: ``` set(int, CAP#1) cannot be applied to (int, Object) required: int, CAP#1 found: int, Object reason: CAP#1 is a fresh type-variable: CAP#1 extends Object from capture of ? ``` The phrase **`capture of ?`** and the name **`CAP#1`** are the compiler's name for the wildcard's unknown actual type, created by **capture conversion**. The list is effectively `List<CAP#1>`, so `set` wants a `CAP#1`. You gave it an `Object` (because `get()` on a `List<?>` returns `Object`), and an arbitrary `Object` is not provably a `CAP#1`. ## Why it happens This is the classic self-referential write on a wildcard list: ```java void rotate(List<?> list) { list.set(0, list.get(1)); // get -> Object, set wants CAP#1 -> error } ``` The value clearly came from the same list, so it IS the right type — but the compiler lost that connection because `get`'s static return type is `Object`, not `CAP#1`. ## The correct fix: capture-helper Give the unknown type a name by passing the list to a generic method: ```java void rotate(List<?> list) { rotateHelper(list); } private <T> void rotateHelper(List<T> list) { list.set(0, list.get(1)); // get -> T, set accepts T: OK } ``` Now capture binds the wildcard to `T`; inside the helper `get` returns `T` and `set` accepts `T`, and the connection is preserved. ## Fixes to avoid - **Casting to `List<Object>`** or **raw `List`** with `@SuppressWarnings("unchecked")` silences the error but reintroduces the unsafety capture was protecting you from — a wrong value could slip in and throw `ClassCastException` later. - **Capturing into a local of type `Object`** doesn't help; you must round-trip through the type variable `T`. ## Takeaways - `CAP#N` / `capture of ?` = the compiler's fresh name for a wildcard's unknown type. - The error means you tried to feed a too-broad type (often `Object`) where the captured type is required. - The clean, type-safe remedy is the generic-helper idiom, not casts or warning suppression.

  • Does the CAP#1 error indicate a runtime problem?
    No — it's a compile-time safety check. The operation may be genuinely safe; you just need to give the compiler a name for the type via a generic helper so it can verify it.
  • Why is casting to List<Object> a bad fix?
    It is unchecked and unsafe: it lets values of the wrong type be written, deferring failure to a ClassCastException at some later, unrelated point.

saying these in an interview costs you the question

  • Fixing it by casting to List<Object> or raw List
  • Adding @SuppressWarnings to silence it
  • Thinking CAP#1 is a real, nameable type
  • Assuming get() returns the captured type (it returns Object)
  • Believing the error indicates a runtime bug rather than a missing capture

context