Primitives in Generics

18
Primitives in Generics current state Ivan St. Ivanov

Transcript of Primitives in Generics

Primitives in Genericscurrent state

Ivan St. Ivanov

Important disclaimer

This is work in progress

Likely to change

I am not an expert

Based on the State of Specialization

document by Brian Goetz (see

resources)

Same things apply to Value Types

The state of generics

Only over reference types

If you want List<int>:List<Integer> intList = new ArrayList<>();

Performance penalty:Heade

rPointer

Pointer

Pointer

Pointer

Heade

rint Heade

rint Heade

rint Heade

rint

But why?

Type erasure in genericspublic class Box<T> {

private T value;public Box(T value) {

this.value = value;}public T get() {

return value;}

}

At runtime T is erased to Object

No common “Object” for primitive and reference types

Why erasure at all?

Use case:

◦ class C uses (or extends) class A

◦ class A is generified

Source and binary compatibility

◦ If class C does not compile: source

incompatibility

◦ If class C should be recompiled to link:

binary incompatibility

No flag day allowed!

Possible approach

Project Valhalla

Compromise #1: current rules for generics should not be changed

Compromise #2: use separate approaches for representing different types

Compromise #3: subclass rules:ArrayList<int> <: List<int> YES

List<int> <: List<Integer> NO

List<int> <: List<?> NO

List<int> <: List NO

Proposed syntax

Introduce any type variable modifierpublic class Box<any T> {

private T value;public Box(T value) {

this.value = value;}public T get() {

return value;}

}

And then:Box<int> intBox = new Box<>(42);

What about byte code?

ErasedBox (for reference types)

SpecialBox (for primitive types)

Side note: translations

Heterogeneous translation◦ Different runtime class for each different

parametric type

◦ Hard to achieve data parametricity (Box<?>)

◦ C++ templates

Homogeneous translation◦ Same runtime type for all different parametric

types

◦ Java achieved it for reference types

◦ C# for reference and structural types

◦ .NET byte code can range over both types, Java - not

Representation in bytecode

Erasure of reference types,

specialization for primitives

Look again at SpecialBox usage site:

Class name augmented with

specialization info

Restrictions for any T

Cannot be converted or compared to null

Cannot be converted to Object or Object[]

Cannot be used as lock for

synchronization

Cannot convert Foo<any T> to Foo<?>

or Foo

Available only for <any T>

Support for new T[size]

Use it where reference type is allowed

(instanceof)

Foo<any T>.class

Generic methods

Workaround for not allowing raw types

to be passed when <any T> is

expected

Implementation:

◦ A version of the <any T> method should be

specialized

◦ Assumption: methods in a class are fixed

◦ invokedynamic is used

<any T> generic method

public class SpecializedMethod {public <any T> T returnValue(T value) { return value; }

public static void main(String[] args) {SpecializedMethod m = new SpecializedMethod();m.returnValue(42);

}}

Bytecode at call site:

Migration challenges

Wrong assumptions in some classes:

T[] array = (T[]) new Object();

Problematic overloading

remove(int position);

remove(T element);

Incompletely generified methods

remove(Object)

There’s no null value for primitives

Possible approach: peeling Implement the backward compatibility method in

reference-specific layer

Add new methods in generic layerinterface List<any T> {void removeByValue(T element);void removeByIndex(int pos);

layer<ref T> {void remove(int pos);void remove(T element);default void removeByIndex(int pos) { remove(pos); }default void removeByValue(T t) { remove(t); }

}}

The erased class will have all methods

The specialized class will only have generic layer methods

Time for experiments ArrayList or Optional class that is generic over

<any T>

Write generic method over <any T> and pass: reference type, primitive and raw type

Specialized classes as method parameters, return types of methods in erased generic or non-generic classes

Usage of static member variables and static methods of specialized classes

Inner classes combination (specialized in specialized, specialized in erased, erased in specialized, specialized in non-generic)

Create new array of T inside specialized generic class

Call instanceof or .class

Resources

State of Specialization (by Brian Goetz)

http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html

Stewardship the Sobering Parts

https://www.youtube.com/watch?v=2y5Pv4yN0b0

Source, binary and behavioral compatibility

https://blogs.oracle.com/darcy/entry/kinds_of_compatibility