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

Java类型擦除探究:JShell中泛型类两种调用场景的疑问

Why Does JShell Output Differ Between Parameterized and Raw Generic Types?

Great question—this difference all comes down to raw types and how Java's type erasure works under the hood. Let's break this down step by step using your two scenarios.

Scenario 1: Using the Parameterized Type X<Integer>

X<Integer> w = new X<Integer>();
w.id(5); // Outputs: 5

When you use the parameterized type X<Integer>, the compiler handles two key details:

  • At compile time, it parameterizes the id method to Integer id(Integer a), enforcing strict type checks (you can’t pass a non-Integer value here without a compile error).
  • After type erasure (Java’s process of stripping generic info at compile time), the runtime method is still Object id(Object a)—but the compiler automatically inserts a cast to Integer when the method returns.

JShell receives an explicitly typed Integer result, so it simply outputs the numeric value 5 with no extra context, exactly as you’d expect.

Scenario 2: Using the Raw Type X

X x = new X<Integer>();
x.id(5); // Outputs: 5 plus additional content

Here you’re using a raw type (omitting the generic parameter <Integer> from the variable declaration X x). Raw types exist to support pre-Java 5 code, and they disable all generic type checks and automatic conversions:

  • At compile time, the compiler treats X as a non-generic class, so the id method’s signature is erased to Object id(Object a). No type checking happens here—you could even pass a String like x.id("test") and it would compile without errors.
  • At runtime, 5 is autoboxed to Integer (which is an Object), passed to the method, and returned as an Object (even though the underlying instance is still Integer).

The "extra content" you see in JShell stems from it handling an Object-typed return value instead of an Integer. Since the type isn’t narrowed down at compile time, JShell may display additional context about the object’s runtime type (or track it as an Object in its variable history) to reflect that the compiler didn’t enforce a specific type here.

Java’s generics are a compile-time only feature—type erasure removes all generic type information before the code runs:

  • For parameterized types, the compiler adds synthetic casts to simulate the generic behavior, making the result feel like a specific type (e.g., Integer).
  • For raw types, we skip those casts and type checks, so we’re working directly with the erased Object type at both compile and runtime. This is why JShell shows extra information: it’s revealing the raw, erased type behavior instead of the "sugared" generic experience.

内容的提问来源于stack exchange,提问作者Mohideen Imran Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:07:29