question on class loading behavior on array classes
ravenex at qq.com
Wed Jan 6 19:40:17 PST 2010
I asked the question on jdk6-dev list, and Joe Darcy said here's a
better place to ask, so here I go.
According the the JVM spec, 2nd edition, 5.3.3 Creating Array Classes,
both the bootstrap class loader and user-defined class loaders can
load array classes, and the corresponding class loaders involved are
recorded as initiating class loaders.
But starting from JDK 6, Sun's JDK by default doesn't allow array
syntax in ClassLoader.loadClass()/ClassLoader.findSystemClass(); array
classes couldn't be created by calling defineClass() anyway, so this
effectively bans user-defined class loaders to be initiating class
loaders for array classes. Calling Class.forName(className,
initialize, classLoader) won't record classLoader as an initiating
class loader for an array class either.
Is this an intended behavior?
I'm expecting a call to Class.forName() would mark the loader as an
initiating one, for all classes (including array classes). That way I
won't have to keep a cache of my own in my custom class loader to keep
track of what's been loaded already. I read Bug 6500212
(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6500212) and know
that I shouldn't call ClassLoader.loadClass() with array syntax, so I
switched to Class.forName(). But then when my class loader is asked to
load the same array class again, it calls findLoadedClass() and gets a
null back. That's pretty bad because I don't won't to get down to
SystemDictionary::resolve_array_class_or_null() every time I load an
array class. That'll force me to use my own cache to record just about
the same info as what the VM already has, plus the array classes
loaded, which looks like a bad smell to me.
And, is it possible for future JDK releases to include more "default
operations" in the reflection API? I mean, something like .NET's Binder
), or just increasing overloads of Class.getMethod()/getMethods()
would be great. The project I'm working on requires lots of reflective
calls, some of which only the receiver type, the target methods name,
the number of arguments, and the exact type of each argument (not
parameter) is known; overload resolution would have to be done at
runtime, where I need to find a best matching overload to invoke. In
.NET, a default Binder provided by the Base Class Library (fetched via
System.Type.DefaultBinder property), and it'll do the overload
resolution for users. I guess it might be more efficient to implement
this kind of feature in the core library, and I wonder what you guys
think. My scenario here is pretty much something like what Fredrik
Ohrstrom's proposed version of MethodHandle's generic invocation
support implements, and if that kind of binding feature exists in the
VM already, exposing it in public API for general consumption should
be easy, I suppose.
More information about the core-libs-dev