Classes, specializations, and statics
Peter Levart
peter.levart at gmail.com
Wed Feb 17 19:32:05 UTC 2016
On 02/17/2016 07:25 PM, Palo Marton wrote:
> Another option is dissalow using T in static field declaration, but
> allow use of T.erased, like this:
>
> class Collection<any T> {
> private __SS Collection<T.erased> emptyCollection = …
>
> private __SS Collection<T> emptyCollection() {
> return (Collection<T>)emptyCollection; // warning
> }
> }
>
> On Wed, Feb 17, 2016 at 6:48 PM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
> Nice catch. Yes, this would cause heap pollution. As would the
> following Java 5 code:
>
> private Collection<?> collection = new ArrayList<?>();
> public <T> Collection<T> c() { return (Collection<T>)
> collection; }
>
> The trouble is, the unchecked warning is in the library
> implementation, not the user code. In the case of an immutable
> collection, we happily suppress the warning knowing that
> everything is safe. If we were returning a mutable collection, it
> would be unsafe to suppress the warning, and doing so would be a
> library bug.
>
> We have several ways out of this hole; one is to restrict
> invocation, as you suggest. Another is to add some unchecked
> warnings. (Another possible path is to treat signatures of erased
> __SS members, when accessed from outside, as if they contained
> capture variables.)
>
There are other problematic situations, like accessing _SS members from
instance members:
public class Foo<any T> {
private _SS List<T> list = new ArrayList<>();
public void add(T element) {
list.add(element);
}
public T get(int i) {
return list.get(i);
}
}
Foo<String> fooStr = new Foo<>();
Foo<Number> fooNum = new Foo<>();
fooStr.add("abc");
Number n = fooNum.get(0);
...or, by analogy, accessing _SS members from generic methods.
Regards, Peter
>
>
>
>
>
> On 2/17/2016 12:03 PM, Peter Levart wrote:
>
> Hi Brian,
>
> On 02/15/2016 07:11 PM, Brian Goetz wrote:
>
> 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.
>
>
> This would work if the emptyCollection was actually empty and
> immutable, but could you do the following:
>
> class Collection<any T> {
> private __SS Collection<T>collection = new ArrayList<T>();
>
> public __SS Collection<T> collection() { return collection; }
> }
>
>
> And then in code:
>
> Collection<String> cs = Collection<String>.collection();
> Collection<Number> cn = Collection<Number>.collection();
>
> cs.add("abc");
> Number n = cn.iterator().next();
>
> If cs and cn hold the same instance, we have introduced heap
> corruption without compilation warnings.
>
> So I suppose in language you could only access the _SS members
> in the following way:
>
> Collection<?>.collection();
> Collection<int>.collection();
> Collection<long>.collection();
> Collection<ValueType>.collection();
> ...
>
> but not:
>
> Collection<Object>.collection();
> Collection<String>.collection();
> ...
>
>
> Like .class literals in the prototype.
>
> Regards, Peter
>
>
>
>
More information about the valhalla-spec-observers
mailing list