Classes, specializations, and statics
Remi Forax
forax at univ-mlv.fr
Mon Feb 15 22:03:50 UTC 2016
The other solution is to allow static field to be parameterized like methods.
private static final <any T> Collection<T> EMPTY = new EmptyCollection<T>();
public static <any T> Collection<T> empty() {
return EMPTY;
}
or perhaps it's just a different syntax of the same solution.
Rémi
----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: valhalla-spec-experts at openjdk.java.net
> Envoyé: Lundi 15 Février 2016 19:11:16
> Objet: Classes, specializations, and statics
>
> M3 leaves us in a position to check off one of the outstanding issues, which
> is that of specialization-specific statics.
>
> Members of Java classes have historically been divided into static and
> instance members; static members are associated with a class, and instance
> members with an instance of a class.
>
> When Java 5 extended the type system to support multiple TYPES that are
> represented by the same CLASS (e.g., ArrayList<String> and
> ArrayList<Number>), we had a choice; treat static members as belonging to
> the CLASS, or as belonging to the TYPE. We chose the former, as that was
> consistent with the translation strategy of erasure, and also maximized
> compatibility with existing code. (When .NET did reified generics, they
> chose the opposite; Foo<Number>.staticMember and Foo<String>.staticMember
> refer different variables. That’s also a valid choice.)
>
> The following program would be sensitive to this distinction:
>
> class Foo<any T> {
> static int count;
>
> public Foo() { ++count; }
> }
>
> new Foo<String>();
> new Foo<Number>();
>
> In Java, this program would increment the common counter twice; under the
> alternative interpretation, the counters Foo<String>.count and
> Foo<Number>.count would each be incremented once.
>
> Statics in Java work the way they do, and we’re not proposing we change that.
> However, once we break the assumption that all instantiations of a
> parameterized type are reference instantiations, we run into some issues
> with existing code idioms. What follows is a proposed generalization of
> static members in the spirit of Model 3.
>
>
> The Problem
> -----------
>
> Java code frequently uses tricks like the following, that exploit the
> assumption of erasure:
>
> // Cached instance of an empty collection
> private static final Collection<?> c = new EmptyCollection<?>();
>
> // Factory method that dispenses the cached empty collections, suitably
> casted
> public static<T> Collection<T> emptyCollection() { return (Collection<T>) c;
> }
>
> The above trick works because of erasure; a Collection<?> has the same
> representation as a Collection<String>, Collection<Integer>, etc, so we can
> freely cast it about with no loss of type safety. But once we anyfy
> emptyCollection(), we’re now hosed; we can’t cast a Collection<?> to a
> Collection<int>. This leaves us without a means of coding this common
> idiom, because static members currently are per-class, not
> per-instantiation.
>
> Obviously, the above code must continue to mean what it means today. But
> we’d also like a means of extending the above idiom more broadly than erased
> generics.
>
>
> Extending Statics to Specializations
> ------------------------------------
>
> Our current model treats parameterizations of template classes like classes;
> anywhere in the bytecode that one can refer to a Constant_Class, one can
> refer to a Constant_ParameterizedType. (Whether they are actually classes,
> or more like “species”, is an open question, but whatever they are, there’s
> a way to write their name in the classfile.)
>
> The existing prototype places static members of Foo<any T> on the erased
> species Class[Foo], and translates access to static member m of Foo<any T>
> as:
>
> xxxstatic Class[Foo].m
>
> However, we are free to assign meaning to xxxstatic as applied to a member
> reference whose owner is a parameterized type. Suppose we extend the
> current set of member ownerships from { instance, static } to { instance,
> static, specialization }. We could then access a per-specialization member
> using xxxstatic on a member reference whose owner is a specialization.
>
> The syntactic story is mostly a bikeshed; we’ll need some token to indicate
> “per-specialization”; we’ll use the silly token __SpecializationStatic for
> now.
>
> The access story is simple: static members continue to only be able to
> reference other static members (and not class type variables); __SS members
> can access static members and other __SS members, as well as class type
> variables; instance members can reference static, __SS, and instance
> members.
>
> The translation / classfile story is simple. Assume we have a spare flag bit
> (we can synthesize one) for ACC_SPECIALIZATION_STATIC (ACC_SS for short.)
> Static members are marked with ACC_STATIC; __SS members are marked with
> ACC_SS. Accesses to static members continue to be translated as xxxstatic
> Class[Foo].m; accesses to __SS members are translated as xxxstatic
> ParamType[Foo,params].m.
>
> The specialization / runtime story is simple. Static members are treated as
> if they are restricted to the erased species (this is a natural choice,
> since Class[Foo] and ParamType[Foo, erased] describe the same class.) __SS
> members become static members on each parameterization. (Both of these are
> one-line changes to the existing specializer prototype.) TypeVar constants
> used in the signature / bodies of __SS members are specialized as usual, and
> just work.
>
>
> Example:
>
> class Collection<any T> {
> private __SS Collection<T> emptyCollection = …
> // ACC_SS field emptyCollection : ParamType[Collection, TypeVar[T]]
>
> private __SS Collection<T> emptyCollection() { return emptyCollection; }
> ACC_SS emptyCollection()ParamType[Collection, TypeVar[T]] {
> getstatic ParamType[Collection, TypeVar[T]].emptyCollection :
> ParamType[Collection, TypeVar[T]]]
> areturn
> }
>
> When we specialize Collection<int>, the field type, method return type, etc,
> will all collapse to Collection<int> by the existing mechanisms.
>
>
>
More information about the valhalla-spec-observers
mailing list