views:

180

answers:

1

I need a method that returns an instance of the supplied class type. Let's assume that the supplied types are limited to such that an "empty" instance of them can be created. For instance, supplying String.class would return an empty String, supplying an Integer.class would return an Integer whose initial value is zero, and so on. But how do I create (boxed) primitive types on the fly? Like this?

public Object newInstance(Class<?> type) {
    if (!type.isPrimitive()) {
        return type.newInstance(); // plus appropriate exception handling
    } else {
        // Now what?
        if (type.equals(Integer.class) || type.equals(int.class)) {
            return new Integer(0);
        }
        if (type.equals(Long.class) // etc.... 
    }
}

Is the only solution to iterate through all the possible primitive types, or is there a more straightforward solution? Note that both

int.class.newInstance()

and

Integer.class.newInstance()

throw an InstantiationException (because they don't have nullary constructors).

+7  A: 

I suspect the simplest way is to have a map:

private final static Map<Class<?>, Object> defaultValues = 
    new HashMap<Class<?>, Object>();
static
{
    defaultValues.put(String.class, "");
    defaultValues.put(Integer.class, 0);
    defaultValues.put(int.class, 0);
    defaultValues.put(Long.class, 0L);
    defaultValues.put(long.class, 0L);
    defaultValues.put(Character.class, '\0');
    defaultValues.put(char.class, '\0');
    // etc
}

Fortunately all these types are immutable, so it's okay to return a reference to the same object on each call for the same type.

Jon Skeet
@Joonas: Have another look now :)
Jon Skeet
Thanks! That might work :)
Joonas Pulakka
I think I'd go for an ?: chain. `type==long.class ? (Long)0L :`, etc.
Tom Hawtin - tackline
@Tom: Any particular reason? Performance? Readability? Once the map is constructed, the method code is basically just the lookup, so that's nice and readable. I'm generally fine with chained conditionals, but in this case I'm not sure I see an advantage. Not much *disadvantage* either, mind you.
Jon Skeet
@Jon: how would you want to change your solution if the OP needed to include mutable classes, like StringBuilder?
CPerkins
@CPerkins: At that point I'd probably change strategy, possibly to something like Tom's suggestion. My answer was aimed at the exact question asked :)
Jon Skeet
I guess the rest of the classes (other than primitive) can be created with the newInstance() method as long as they have a nullary constructor. So I just need to check whether the supplied class type is primitive or not, and then return an instance created with Jon's map system or with newInstance().
Joonas Pulakka
Err, except that for instance Integers are not primitive, so I must check against all wrapper classes too!
Joonas Pulakka