Skip to content

Java Source: Updated ClassUtils.java

In a recent project I was working on I ran into a couple of wrinkles with my ClassUtils class. The first problem was regarding the specialized instantiation methods, those that instantiate a class only if it extends a specific superclass or implements a specific interface. Because I opted to return null from these methods on failure rather than throwing exceptions, there was no way to know if a null return was due to a failed instantiation or because the class did not extend or implement the specified superclass or interface. The second problem was that there was no public method to instantiate a new instance from a Class object rather than a class name.

Both problems were easy fixes. All specialized instantiation methods now return null immediately when instantiation fails. If the class does not implement or extend the given interface or superclass, there is now an option to log this case. You have to implement it yourself, though, if you want to use it. In my local copy, I log all of instantiation failures and subclass/interface implementation mismatches to file. I did not add that to the copy I posted here in order to avoid any external dependencies. Whatever you use, it pays to implement logging in the sections I have commented out for it.

The second problem was one I had not foreseen. Until my recent project, I had always looked up a class before instantiating an instance of it. But I ran into a situation where I needed to instantiate multiple instances of classes that implement a particular interface. The instantiations happen frequently enough and in large enough numbers that this could potentially be a bottleneck, but there was no way to know for sure until later on in development when I would have enough classes to test with. Early on, there just wasn’t enough going on to get the big picture. As a preemptive measure, I realized the best thing to do would be to cache the Class object and instantiate from that rather than calling ClassUtils.instantiateIfImplements every time. Because the classes are unknown at compile time (class names are read in from a properties file), I still have to dynamically instantiate at least one instance through ClassUtils.instantiateIfImplements to verify that it does, indeed, implement the given interface.

ClassUtils already had a private method that was used internally by the different instantiation methods, so I made it public and changed its name. Now you can call ClassUtils.instantiateObject with a class name or with a Class object as the single parameter to instantiate any class. That allows you to do things like this:

class MyInterfaceFactory {

    private Class cachedClass;

    public MyInterfaceFactory(String className) {
        MyInterface mi = ClassUtils.instantiateIfImplements(className, MyInterface.class.getName());
        if(mi != null)
            cachedClass = mi.class;
        else
            cachedClass = null;
    }

    public MyInterface create() {
        // ClassUtils.instantiateObject will return null if the clazz parameter
        // is null, so no need to test cachedClass for null
        return (MyInterface)ClassUtils.instantiateObject(cachedClass);
    }
}

This technique is very useful when you frequently want to instantiate a number of objects which implement a specific interface or extend a specific class, but the class name is not known at compile time. By caching the class instance, you avoid the overhead of verifying that the class does implement an interface or extend a class on every instantiation. It only needs to be done once at startup.

Feel free to download ClassUtils.java and use it in any way you please. If you find any bugs, please let me know. This is a modified version of what I use locally and I haven’t tested it at all myself, so there could very well be errors somewhere.

Technorati Tags: ,

Post a Comment

Your email is never published nor shared. Required fields are marked *