문제

We have generic class

SomeClass<T>{ }

We can write the line:

SomeClass s= new SomeClass<String>();

It's ok, because raw type is supertype for generic type. But

SomeClass<String> s= new SomeClass();

is correct to. Why is it correct? I thought that type erasure was before type checking, but it's wrong.

From Hacker's Guide to Javac

When the Java compiler is invoked with default compile policy it performs the following passes:

  1. parse: Reads a set of *.java source files and maps the resulting token sequence into AST-Nodes.
  2. enter: Enters symbols for the definitions into the symbol table.
  3. process annotations: If Requested, processes annotations found in the specified compilation units.
  4. attribute: Attributes the Syntax trees. This step includes name resolution, type checking and constant folding.
  5. flow: Performs data ow analysis on the trees from the previous step. This includes checks for assignments and reachability.
  6. desugar: Rewrites the AST and translates away some syntactic sugar.
  7. generate: Generates Source Files or Class Files.

Generic is syntax sugar, hence type erasure invoked at 6 pass, after type checking, which invoked at 4 pass. I'm confused.

도움이 되었습니까?

해결책

The type parameter definitely participate in type checking; otherwise it will be pointless (i.e. no better than raw types).

The information is also needed to generate implicit casts so it will survive to your step 7 and technically to runtime as debug symbols. However, only the erasure will participate in runtime type cast checking (for obvious backwards compatibility reasons). Nonetheless, if your generic code can be fully statically checked, it can be as strong as generic programs in non-type-erasure languages.

When you assign SomeClass to SomeClass<String>, the compiler will give you a warning about raw type use. At this point, your program is obviously no longer safe.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top