FYI: (Incident Review ID: 1684743) Compiler type- & existence-checked reflection syntax sugar via new ".." operator

Matthew Adams matthew at matthewadams.me
Fri Jan 8 10:57:06 PST 2010


FYI, I submitted this suggestion to Sun and it just got reviewed and
assigned an RFE id.  See below.


---------- Forwarded message ----------
From: Sun Microsystems <IncidentUpdateDaemon at sun.com>
Date: Fri, Jan 8, 2010 at 12:54 AM
Subject: Re: (Incident Review ID: 1684743) Compiler type- &
existence-checked reflection syntax sugar via new ".." operator
To: matthew at matthewadams.me


--- Note: you can send us updates about your Incident ---
--- by replying to this mail.  Place new information  ---
--- above these lines.  Do not include attachments.   ---
--- Our system ignores attachments and anything below ---
--- these lines.                                      ---

Hi Matthew Adams,

Thank you for taking the time to suggest this enhancement to the Java
Standard Edition.

We have determined that this report is an RFE and has been entered into our
internal RFE tracking system under Bug Id: 6915224

You can monitor this RFE on the Java Bug Database at:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6915224

It may take a day or two before the RFE shows up in this external
database. If you are a member of the Sun Developer Network (SDN),
there are two additional options once the bug is visible.

1. Voting for the RFE
  Click http://bugs.sun.com/bugdatabase/addVote.do?bug_id=6915224

2. Adding the report to your Bug Watch list.
  You will receive an email notification when this RFE is updated.
  Click http://bugs.sun.com/bugdatabase/addBugWatch.do?bug_id=6915224

The Sun Developer Network (http://developers.sun.com) is a free
service that Sun offers.  To join, visit
https://softwarereg.sun.com/registration/developer/en_US/new_user.

SDN members can obtain fully licensed Java IDEs for web and enterprise
development.  More information is at
http://developers.sun.com/prodtech/javatools/free/.

We greatly appreciate your efforts in identifying areas in the Java
Standard Edition where we can improve upon and I would request you to
continue doing so.

Regards,
Nelson

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
NOTICE: This message, including any attachments, is for the intended
recipient(s) only.  If you are not the intended recipient(s), please
reply to the sender, delete this message, and refrain from disclosing,
copying, or distributing this message.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------- Previous Messages ----------------


--------------------- Report ---------------------

     category : java
  subcategory : classes_lang
      release : 7
         type : rfe
     synopsis : Compiler type- & existence-checked reflection syntax
sugar via new ".." operator
 customer name : Matthew Adams
 customer mail : matthew at matthewadams.me
       sdn id :
     language : en
      company : Matthew Adams Consulting, Inc.
     hardware : x86
           os : win_xp
       bug id : 6915224
 date created : Sun Dec 27 09:30:10 MST 2009
date evaluated : Fri Jan 08 01:53:22 MST 2010
  description :
A DESCRIPTION OF THE REQUEST :
Add a new operator ".." to allow compile-time type-checked and
existence-checked reflection access.

JUSTIFICATION :
1. There is no compile-time typesafe way to gain access via reflection
to fields, methods, constructors, annotations, etc.
2. The code to obtain aforementioned artifacts can become verbose.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
See project-coin dev list email:
http://mail.openjdk.java.net/pipermail/coin-dev/2009-December/002638.html

Copied here for convenience:
Proposal:
Compile-time type-checked and existence-checked reflection syntax

 Description:
Introduce a new, double-dot operator ".." to act as syntax sugar for
accessing reflection information with type & existence checking at
compile time.

Concept:
The double-dot operator, meaning "get metamodel artifact", allows for
much more concise reflective access to things you know about at build
time but must use reflection for some reason.  Trust me, it happens
plenty.  The choice of ".." for the operator was that first, ".."
doesn't introduce a new keyword, and second, in filesystems, ".."
usually means "go up a level", which is essentially what we're doing:
going up a level from model to metamodel.  Looking at the examples,
you can see how much less code it is compared to the reflection-based
equivalent, plus if it's typesafe, you get fewer errors when you're
depending on type safety -- that is, at least you knew at compile time
that things were all good.  It still doesn't mean anything at runtime,
and you could get NoSuchMethodException, etc.

Examples:

1. Get the Field object for the field named "bar" in class Foo:
Field bar = Foo..bar;

// current way
Field bar = Foo.class.getDeclaredField("bar");

2. Get the Method object for the method with signature "myMethod(int
a, String y)" defined on class Goo:
Method m = Goo..myMethod(int,String);
// note scope & return type don't matter

// current way
Method m = Goo.class.getDeclaredMethod("myMethod", new
Class[int.class, String.class] {});

3. Get the Class object for the class Snafu.  This is an interesting
case that offers backward compatibility:
Class c = Snafu..class;
// exactly the same as Snafu.class, the ".." operator's insipiration!!

4. Get the @Foo annotation on the Bar class:
Annotation foo = Bar.. at Foo;

// current way
Annotation foo = Bar.class.getAnnotation(Foo.class);

5. Get the @Foo annotation on the field named "blah" in the class Gorp:
Annotation foo = Gorp..blah.. at Foo;

// current way
Annotation foo = Gorp.class.getDeclaredField("blah").getAnnotation(Foo.class);

6. Get the @Foo annotation on the second parameter of the method
"start(int x, @Foo int y, int z)" defined in class Startable:
Annotation foo = Startable..start(int,int.. at Foo,int);

// current way -- no error checking
Annotation[] anns = Startable.class.getMethod("start", new Class[] {
int.class, int.class, int.class }).getParameterAnnotations()[1];
Annotation foo = null;
for (Annotation ann : anns) {
 if (ann.getClass().equals(Foo.class)) {
   foo = ann;
   break; // got it
 }
}
// foo is either null or a reference to the @Foo annotation instance
on the second parameter of the method

7. Get all of the @Foo annotations on all of the parameters of the
methods "start(@Foo int x, int y, @Foo int z)" defined in class
Startable:
Annotation[] foo = Startable..start(int.. at Foo,int.. at Foo,int.. at Foo);
// returns an array with the first @Foo, null, then the last @Foo

// current way left as an exercise to the reader :)

8. Get the @Foo annotation on the "@Foo start(int x, int y, int z)"
method defined in class Startable:
Annotation foo = Startable..start(int,int,int).. at Foo;

// current way
Annotation foo = Startable.class.getDeclaredMethod("start", new
Class[] { int.class, int.class, int.class }).getAnnotation(Foo.class);


Motivation:

The double-dot operator would allow for compile-time type-checked
reflective operations, like those in the persistence APIs.  For
example, in JPA:

@Entity
public class Department {
 @OneToMany(mappedBy = "department") // note string
 Set<Employee> employees;
 //...
}

becomes

@Entity
public class Department {
 @OneToMany(mappedBy = Employee..department) // checked at compile time
 Set<Employee> employees;
 //...
}

It also is beneficial in many other areas.  Use your imagination!  I
can't think of many more (it's late), but Criteria queries come to
mind...


ACTUAL -
See project-coin dev list email:
http://mail.openjdk.java.net/pipermail/coin-dev/2009-December/002638.html

Copied here for convenience:
Proposal:
Compile-time type-checked and existence-checked reflection syntax

 Description:
Introduce a new, double-dot operator ".." to act as syntax sugar for
accessing reflection information with type & existence checking at
compile time.

Concept:
The double-dot operator, meaning "get metamodel artifact", allows for
much more concise reflective access to things you know about at build
time but must use reflection for some reason.  Trust me, it happens
plenty.  The choice of ".." for the operator was that first, ".."
doesn't introduce a new keyword, and second, in filesystems, ".."
usually means "go up a level", which is essentially what we're doing:
going up a level from model to metamodel.  Looking at the examples,
you can see how much less code it is compared to the reflection-based
equivalent, plus if it's typesafe, you get fewer errors when you're
depending on type safety -- that is, at least you knew at compile time
that things were all good.  It still doesn't mean anything at runtime,
and you could get NoSuchMethodException, etc.

Examples:

1. Get the Field object for the field named "bar" in class Foo:
Field bar = Foo..bar;

// current way
Field bar = Foo.class.getDeclaredField("bar");

2. Get the Method object for the method with signature "myMethod(int
a, String y)" defined on class Goo:
Method m = Goo..myMethod(int,String);
// note scope & return type don't matter

// current way
Method m = Goo.class.getDeclaredMethod("myMethod", new
Class[int.class, String.class] {});

3. Get the Class object for the class Snafu.  This is an interesting
case that offers backward compatibility:
Class c = Snafu..class;
// exactly the same as Snafu.class, the ".." operator's insipiration!!

4. Get the @Foo annotation on the Bar class:
Annotation foo = Bar.. at Foo;

// current way
Annotation foo = Bar.class.getAnnotation(Foo.class);

5. Get the @Foo annotation on the field named "blah" in the class Gorp:
Annotation foo = Gorp..blah.. at Foo;

// current way
Annotation foo = Gorp.class.getDeclaredField("blah").getAnnotation(Foo.class);

6. Get the @Foo annotation on the second parameter of the method
"start(int x, @Foo int y, int z)" defined in class Startable:
Annotation foo = Startable..start(int,int.. at Foo,int);

// current way -- no error checking
Annotation[] anns = Startable.class.getMethod("start", new Class[] {
int.class, int.class, int.class }).getParameterAnnotations()[1];
Annotation foo = null;
for (Annotation ann : anns) {
 if (ann.getClass().equals(Foo.class)) {
   foo = ann;
   break; // got it
 }
}
// foo is either null or a reference to the @Foo annotation instance
on the second parameter of the method

7. Get all of the @Foo annotations on all of the parameters of the
methods "start(@Foo int x, int y, @Foo int z)" defined in class
Startable:
Annotation[] foo = Startable..start(int.. at Foo,int.. at Foo,int.. at Foo);
// returns an array with the first @Foo, null, then the last @Foo

// current way left as an exercise to the reader :)

8. Get the @Foo annotation on the "@Foo start(int x, int y, int z)"
method defined in class Startable:
Annotation foo = Startable..start(int,int,int).. at Foo;

// current way
Annotation foo = Startable.class.getDeclaredMethod("start", new
Class[] { int.class, int.class, int.class }).getAnnotation(Foo.class);


Motivation:

The double-dot operator would allow for compile-time type-checked
reflective operations, like those in the persistence APIs.  For
example, in JPA:

@Entity
public class Department {
 @OneToMany(mappedBy = "department") // note string
 Set<Employee> employees;
 //...
}

becomes

@Entity
public class Department {
 @OneToMany(mappedBy = Employee..department) // checked at compile time
 Set<Employee> employees;
 //...
}

It also is beneficial in many other areas.  Use your imagination!  I
can't think of many more (it's late), but Criteria queries come to
mind...



---------- BEGIN SOURCE ----------
No test cases yet.
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Workaround is conventional reflection-based code.




-- 
mailto:matthew at matthewadams.me
skype:matthewadams12
yahoo:matthewadams
aol:matthewadams12
google-talk:matthewadams12 at gmail.com
msn:matthew at matthewadams.me
http://matthewadams.me
http://www.linkedin.com/in/matthewadams



More information about the coin-dev mailing list