java.lang.constant.ClassDesc and TypeDescriptor for hidden class??

John Rose john.r.rose at
Fri Apr 3 05:03:09 UTC 2020

On Apr 2, 2020, at 11:34 AM, Brian Goetz <brian.goetz at> wrote:
> Mandy reminded me that descriptorString() is specified to return a JLS 4.2.3 field descriptor, and so (c) would violate that spec.  I think this tilts the table away from (c), even though this string is arguably useful (though not clear to whom.)  

Here’s a compromise that almost makes sense on its own:

(d) return the field descriptor string for the hidden class,
minus the “.X” suffix, appropriately wrapped.

First of all, it’s a valid descriptor.  (Though probably not
resolvable to a class, still its valid.)  Second, it’s arguably
how the HC’s descriptor *would* be spelled as a field
descriptor, if it could.  The CONSTANT_Class entry of
the original ClassInfo.this_class of the HC has that
class name, sans added “.X”.

But, I think the best compromise is to admit that, just
as Class::getName returns an intentionally invalid
though suggestive class name (rather than null or an
exception), so Class::descriptorString should return
the intentionally invalid though suggestive field
descriptor which is regularly derived from said
Class::getName.  This provides consistency in
string-valued outputs; in the absence of an argument
why their treatment should be inconsistent,
consistency is less confusing and should win.

The validity checking in the constructor of
ReferenceClassDescImpl already ensures that such
a HC descriptor string cannot be mistaken for a
well-formed field descriptor, since it excludes dots “.”
in the input.  I think *that* is the right place to
put the error check, and it’s no accident (this time)
that the prototype code behaves this way, because
complicating the spec. with extra validity checks
would also require more validity checks for the
affected method (Class::descriptorString).

Under this theory, the code needs one more validity

    public Optional<ClassDesc> describeConstable() {
   +     if (isHidden()) return Optional.empty();
        return Optional.of(ClassDesc.ofDescriptor(descriptorString()));

If that validity check is missing, then ClassDesc.of would
throw (in the constructor referred to above), violating
the convention 0f using Optional.empty().

— John

More information about the valhalla-dev mailing list