You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java泛型super/extends行为差异(OCP Java 8备考)

Understanding extends vs super in Java Generics (OCP Java 8 Focus)

Hey there! Since you're prepping for OCP Java 8 and already have a solid grasp on List<? super A> behavior, let's dive into how the extends wildcard differs—using your class hierarchy as a reference to make things concrete.

First, let's recap your class structure for clarity:

java.lang.Object
class A extends Object {
    public boolean mA() {return true;}
}
class B extends A {
    public boolean mB() {return false;}
}

1. What List<? extends A> accepts as arguments

Unlike List<? super A> (which takes ArrayList<A> or ArrayList<Object>), List<? extends A> can only work with lists of A or its subclasses. That means valid arguments include:

  • new ArrayList<A>()
  • new ArrayList<B>()
  • Any other list where the generic type is a subclass of A

You cannot pass an ArrayList<Object> here—since Object is a superclass of A, not a subclass, it violates the extends constraint.

2. Behavior of get() with extends

When you call get() on a List<? extends A>, the compiler guarantees the returned object is an instance of A (or a subclass of A). This is safe because every subclass of A inherits from A, so you can safely call methods defined in A on the returned item.

Example:

public static void m2(List<? extends A> l) {
    A retrievedItem = l.get(0); // Compiles perfectly
    retrievedItem.mA(); // Works—mA() is defined in A
    // retrievedItem.mB(); ❌ Compile error! We can't guarantee the item is a B
}

Compare this to your List<? super A> example, where get() only returns Object—you were limited to calling Object methods like toString().

3. Behavior of add() with extends

This is where the biggest contrast with super comes in: you cannot add any non-null elements to a List<? extends A>.

Why? The compiler doesn't know the exact type of the list. For example:

  • If the list is actually a List<B>, adding an A instance would be invalid (since A is a superclass of B, not a subclass).
  • Even adding a B instance isn't allowed—because the list could be a plain List<A>, but the compiler errs on the side of safety to avoid runtime errors.

The only exception is null, since null is a valid value for any reference type:

public static void m2(List<? extends A> l) {
    l.add(new A()); // ❌ Compile error
    l.add(new B()); // ❌ Compile error
    l.add(null); // ✅ Works—null is compatible with all types
}

Again, contrast this with List<? super A>, where you can freely add A or B instances (since any superclass of A can hold A and its subclasses).

4. The PECS Rule (Key for OCP)

To remember the difference, use the PECS principle (Producer Extends, Consumer Super):

  • Use extends when your code is producing elements from the list (reading/getting items)—you're pulling items out, and you know they're at least of the upper bound type (A).
  • Use super when your code is consuming elements into the list (writing/adding items)—you're putting items in, and you know the list can accept at least the lower bound type (A) and its subclasses.

That's the core of the behavior difference—this will be critical for your OCP exam questions on generics!

内容的提问来源于stack exchange,提问作者Ricardo Fonseca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:26:12