PROPOSAL: language support for JSR 292

Joseph D. Darcy Joe.Darcy at Sun.COM
Fri Apr 3 01:25:07 PDT 2009


Some comments interspersed.

John Rose wrote:
> Here is a text form of the proposal, for the archives.  The wiki form  
> should be equivalent at the moment, but as edits are made the wiki  
> form will be normative.
> Best wishes,
> -- John
> John Rose
> Create source-code syntaxes for using new JVM features from JSR 292.   
> These are invokedynamic instructions, method handle invocation,  
> certain relaxed conversions, and exotic identifiers.


> 1.3 Any call to a method in Dynamic accepts an optional type parameter  
> which specifies the return type of the call site's descriptor.  The  
> type parameter may any type whatever, including void or a primitive  
> type.  If it is omitted it defaults to the type java.dyn.Dynamic  
> itself.  (See part 4 for conversion rules involving Dynamic.)

Reiterating a point Neal raised, if Dynamic is not related to Object, 
what does that mean when Dynamic is used as the format type argument to 
a type parameter?  What do "? extends Dynamic" and "? super Dynamic" 
mean to the type system?

>      Dynamic x = Dynamic.myGetCurrentThing();  // type () -> Dynamic
>      Dynamic.<void>myPutCurrentThing(x);  // type (Dynamic) -> void
>      int y = Dynamic.<int>myHashCode((Object)x);  // type (Object) ->  
> int
>      boolean z = Dynamic.<boolean>myEquals(x, y);  // type (Dynamic,  
> int) -> boolean
> (Rationale: Although it is strange for non-references to appear in the  
> syntactic position of type arguments, this design is far simpler than  
> inventing a completely new syntax for specifying the return type of  
> the call site, as some early prototypes did.)
> 1.4 For the purposes of determining the descriptor of the  
> invokedynamic instruction, null arguments (unless casted to some other  
> type) are deemed to be of reference type java.lang.Void.  This is a  
> pragmatic choice, compatible with the verifier and partially coherent  
> with the meaning of the type Void, since it happens to allow only null  
> reference values.  Conversely, void method return values are reflected  
> as null values.  The type Void will appear only to the bootstrap  
> method, and will serve notice that the call site contains a null,  
> rather than an explicitly typed reference.
>      Dynamic.myPrintLine(null);  // type (Void) -> Dynamic
>      Dynamic.<void>foo((String)null, null);  // type (String, Void) ->  
> void
> 1.5 No checked exceptions are produced by any call to Dynamic.
>      try {; } catch (Exception ee) { }  // a compile- 
> time error

Actually there is a special rule that catching Exception is always okay 
per JLS 11.2.3; this program is legal and compiles fine:

public class Test {
    public static void main(String... args){
    try {
    } catch (Exception e) {


> 2.2 Any reference of type MethodHandle may be qualified with the  
> method name "invoke" and invoked on any number and type of arguments.   
> Only the method named "invoke" is treated this new way.  All other  
> expressions involving MethodHandle are unchanged in meaning, including  
> selection of members other than "invoke", casting, and instanceof.
>      MethodHandle mh = ...;
>      mh.invoke("foo", 42);  // argument types (String, int)
>      MethodType mtype = mh.type();  // no new rules here; see JSR 292  
> javadocs
>      mh.neverBeforeSeenName();  // no new rules; must raise an error
> In effect, java.dyn.MethodHandle appears to have an infinite number of  
> non-static methods named "invoke", of every possible signature.
> (In fact, JSR 292 specifies that each individual method handle has a  
> unique type signature, and may be invoked only under that specific  
> type.  This type is checked on every method handle call.  JSR 292  
> guarantees runtime type safety by requiring that an exception be  
> thrown if a method handle caller and callee do not agree exactly on  
> the argument and return types.  The details of this check are not part  
> of this specification, but rather of the MethodHandle API.)

So what are the notions of identity and equality for method handles?

> 4.1 As specified above, the interface java.dyn.Dynamic has no  
> supertypes or members.  As such, it is a bare reference type.  (As an  
> arbitrary relation, the superclass of Dynamic[] is Object[].)  We  

Are there any other type building operations besides arrays we need to 
worry about?


> 4.6 The expression syntaxes with predefined meaning for dynamic sub- 
> expressions are those which perform the conversions described above.   
> These are assignment "=" and casts.  Dynamic expressions may also be  
> tested with instanceof.  Also, Dynamic values may be declared,  
> assigned to variables, passed as method or constructor arguments, and  
> returned from methods.
> But, the Java operators "==" "!=" "+" "+=" on reference types are  
> clarified to apply only to reference types which are java.lang.Object  
> or one of its subtypes; they do not have a predefined meaning if  
> either operand is dynamic.  The "synchronized" and "throw" statements  
> cannot be applied to dynamic expressions.

So if there is no predefined meaning, are those operations illegal?


> The method java.lang.Class.getDeclaredMethod must be special-cased to  
> always succeed for MethodHandle.invoke and for Dynamic (any method  
> name), regardless of signature.  The JSR 292 JVM has this logic  
> already, but it must be exposed out through the Class API.
> Only single-result reflection lookups need to be changed.  Multiple- 
> method lookups should *not* produce implicitly defined methods.
> The javax.lang.model API (which is used internally by javac) does not  
> need specialization, because the implicitly defined methods of  
> MethodHandle and Dynamic do not ever need to mix with other more  
> normal methods.  The static (compile-time) model of Dynamic may not  
> present any enclosed elemeents, while that of MethodHandle must not  
> present any methods named "invoke".
> Facilities which compute type relations (such as  
> javax.lang.model.util.Types) may need to be updated to take Dynamic  
> into account.  Generally speaking, the new Dynamic conversions operate  
> in parallel to the implicit boxing conversions.  That is, they add no  
> new subtype or supertype relations, but they provide a few more ways  
> for values to be implicitly converted or casted.

Yes, I would expect a few changes to the type-related APIs.  They may 
also need to be changes to programs that assume Object is the root of 
the reference type hierarchy.  I know I've written annotation processing 
code like that and Dynamic would need to be special cased in there.


More information about the coin-dev mailing list