jdk1.4
for example,
Class.forName(java.lang.Character.UnicodeBlock);
does not find class object for the nested class.
To get around this problem I had to
class.forName(java.lang.Character$UnicodeBlock);
bae-chul.kim@eng 2000-10-11
Comments
EVALUATION
The fully qualified name for a nested class does not contain '$'. It contains
'.' as in "java.lang.Character.UnicodeBlock". The presence of the '$' is merely
an artifact of the compiler implementation, it is not specified in the JLS.
According to JLS 2nd ed, section 6.7:
A member class or member interface M of another class C has a fully
qualified name if and only if C has a fully qualified name. In that case,
the fully qualified name of M consists of the fully qualified name of C,
followed by ".", followed by the simple name of M.
A '$' should not be necessary to specifiy the nested class name. After speaking
to ###@###.### and ###@###.###, we have come to the conclusion that we
should allow classnames with '$' to continue to work for compatibility reasons
and make '.' work.
The implementation of Class.forName is in native code. The actual lookup
is handled by a call to JVM_FindClassFromClassLoader(). Logically, what we'd
like to do is take the user-provided string which specifies the fully qualified
name, replace all '$' with '.' where the '$' represents the divider for a java
identifier then call JVM_FindClassFromClassLoader().
Potential problems:
- initialization - Inner classes do not have static state or initializers. The
current primary effect of initialization is to initialize the superclass.
More details provided in the "comments" section.
- ambiguities - Consider the following examples:
package a;
class b {
class c {}
}
package a.b;
class c {}
Under the new proposed scheme, both cases would be reference with "a.b.c".
The class returned would depend entirely on the algorithm used by
JVM_FindClassFromClassLoader(). Determined to be highly unlikely, especially
if users of Class.forName follow standard conventions for package and class
names.
- '$' as part of a java identifier
- class $a {}
This and other cases where the identifier begins with '$' will not be
transformed.
- class a$b {}
Unfortunately, the '$' will be transformed to '.'. It is unclear at this
time what the behaviour would be. It is possible that by the nature of the
JVM's search algorithm will allow this class to be located. This case
represents a potential change in behaviour.
Hopefully due to the use of '$' by the compiler, such cases will be extremely
rare.
Misc Notes:
- At the current time, it appears that the JVM function expects a "slashed
name" to conform to the JVM Spec, 2nd ed, section 4.2. I would presume that
this requirement will not change.
- ###@###.### recommends investigating whether it makes sense for
the JVM to change the separator from '$' for all inner members (classes,
fields, etc.) for performance reasons. The debugger may also need to be
updated to handle this. This analysis/decision is outside of my area of
expertise.
- The javac implemenation will not be changed. This is a VM/library problem
only.
-- iag@sfbay 2002-01-22
###@###.### 2002-01-23
If there is any amiguity in behavior, such as forName("A.B") meaning
either A$B.class or A/B.class, then the JLS must be modified to specify
which choice is the correct one.
If one choice is chosen to be dominant, then there must be a mechanism
for a user to specify the other choice.
The author of package A and the author of package A.B now have to negotiate
which of them owns the name "A.B". These authors may not know each other.
If we make the change, then the JLS (and perhaps the JVMS) must change to
specify these behaviors (or we don't have WORA). And if we change the
JLS, why not just document the "$" use, avoid the ambiguities and be
done with it.
This bug should not be fixed.
-----
Ideally, this bug should be fixed. However, after more discussion, we have
reluctantly concluded that this bug can not be fixed due to the ambiguity
problems mentioned above, possible efficiency problems in the VM, and API
consistency problems (e.g. Class.getName should return something which is
acceptable to Class.forName). See the "comments" section for more details.
Bug 4628117 contains the request for the spec for Class.forName to clarify what
is currently being returned.
-- iag@sfbay 2002-01-24