[JSR308] Enhanced for loops
Artemus Harper
subanark at gmail.com
Sat Aug 9 18:45:44 EDT 2008
>
> Your proposal would require each 'E' in the interface to be '@Unique({"T"})
> E'. This clatters the interface. Furthermore, even clients who don't care
> about uniqueness would need understand this interface.
>
There are some subclassing problems with generics (that I forgot to mention
last time). You cannot keep the generic information if you do an upcast.
I am faced with the problem that the overridable methods in Object are not
safe. The standard implementation of toString() for a collection is to call
toString() on each of its members. But what if the collection is typed as
having @Unique elements? The implementation of toString() for the elements
may leak its reference, so toString() must be prohibited. But even if we
marked toString() as not being callable if the elements are unique you would
have to prohibit a cast to Object, otherwise toString() can be called since
the toString() method does not prohibit calling if the invokee is
unannotated.
So, an annotation to prohibit calling toString() is needed. I do this simply
by not annotating toString() in Object indicating that toString() may only
be called if the reference is known not to be @Unique.
E.g.
public class MyClass
{
static BadObject o;
public static class BadObject //Default constructor inherrits @NoEscape
annotation from Object's constructor.
{
@Override public String toString()
{
o = this.
return "Bad Object";
}
public static void main(String[] args)
{
UniqueList<@Unique BadObject> list = new UniqueList<@Unique
BadObject>();
list.add(new BadObject()); //Constructor is @NoEscape so a @Unique
object is created with new.
Object olist = list;
olist.toString(); //how to prevent this? This makes the static
variable o assigned to a supposdly unique element.
}
}
What happens with my Annotations:
public class MyClass
{
static BadObject o;
public static class BadObject //Default constructor inherrits @NoEscape
annotation from Object's constructor.
{
@Override public String toString()
{
o = this.
return "Bad Object";
}
public static void main(String[] args)
{
@InnerUnique({"T"}) UniqueList<BadObject> list = new UniqueList<
BadObject>(); //annotation inferred for new
list.add(new BadObject()); //Constructor is @NoEscape so a @Unique
object is created with new.
Object olist = list; //not valid to remove the @InnerUnique
annotation
@InnerUnique({"T"}) Object olist = list;
olist.toString(); //Not valid since toString() is not annotated to
allow this.
}
}
Now, if Object.toString() was @NoEscape (or if some subclass added this
annotation) the we could freely invoke toString() as the implementors would
need to ensure that the reference does not leak. Although this is true for
the vast majory of implementations, it is notably not true for the String
class (since it returns itself, which by my defination escapes).
I *could* retrofit the syntax so that the generic parameter is an alias for
the InnerUnique on the same name as the parmeter. In addition to having
interfaces automatically annotated with the unknown generic annotation.
As an aside I am considering doing away with InnerUnique and instead
represent it with array notation, so that @InnerUnique({"T"}) becomes
@Unique({"[T]"})
But...
>> 1. I would need 2 additional annotations: MaybeUnique and NotUnique. The
>> first would be needed to indicate that the class supports the Unique
>> annotation on its type, the second for cases where the method cannot be
>> executed for unique parameters.
>>
> How do you represent such constraints with InnerUnique? I thought that you
> actually needed this.
I add this information into the value() of the annotation:
@Unique: The reference is unique
@Unique ({"T"}) : The reference is unique if "this" is InnerUnique({"T"})
otherwise its not.
@Unique ({"?"}) : The reference's uniqueness is unknown same as @NoEscape
@InnerUnique({"T"}) : All parameters, return type, and receiver with
@Unique({"T"}) is @Unique
@InnerUnique({"?T"}) : All parameters, return type, and receiver with
@Unique({"T"}) are @Unique{("?"})
@InnerUnique({"T->E"}) : If "this" is InnerUnique({"T"}) then the reference
is @InnerUnique({"E"})
@InnerUnique({"?"}) : All parameters, return types, and receivers with a
conditional @Unique is @Unique({"?"})
--
Artemus Harper
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.csail.mit.edu/pipermail/jsr308/attachments/20080809/fd555e29/attachment-0001.htm
More information about the JSR308
mailing list