`List<?> xs` cannot have any non-null element added to it, even `xs.set(0, xs.get(0))` — putting back exactly what was just read out fails to compile. But a private helper method with a type parameter can swap two elements of the same `List<?>` just fine. Explain the compiler mechanism that makes the second case work, precisely — not just "it captures the type."
List<?> means "a list of some specific but completely unknown element type," and every time the compiler type-checks an expression involving that list, it invents a fresh, anonymous stand-in for that unknown type — shown in error messages as CAP#1 — and checks the expression as if the list were List<CAP#1>. Two separate uses of the same wildcarded variable, like xs.get(0) and xs.set(0, ...) written as two different statements, or worse, within a single expression, each get their own, independently-invented CAP#1, and the compiler has no way to prove those two invented stand-ins are actually the same type, even though at run time they obviously are — so xs.set(0, xs.get(0)) fails because the value handed to set (typed as whatever CAP#1 the get() call invented) can't be proven to be a CAP#1 matching the different CAP#1 that set's own parameter type expects. A generic helper method fixes this because calling it passes the same List<?> through a single call, and the compiler captures the wildcard exactly once, for that one call, binding it to the helper's own type parameter T — inside the helper, every reference to that parameter is provably the same T, because it's one variable bound once, not two independent, unrelated invented types.