yegor256
yegor256

Reputation: 105053

How to instantiate Class class for a primitive type?

I'm trying to do this, but doesn't work:

public static Class loadIt(String name) throws Throwable {
  return Class.forName(name);
}
assert foo.loadIt("int") == int.class; // exception here

How should I do this properly?

Upvotes: 22

Views: 19358

Answers (5)

Naman
Naman

Reputation: 31878

Going forward this can be achieved in a much simpler way with Class#forPrimitiveName introduced in Java-22 stating:

Returns the Class object associated with the primitive type of the given name. If the argument is not the name of a primitive type, null is returned.

Class<?> anInt = Class.forPrimitiveName("int");
assert anInt == int.class;

Upvotes: 1

rmuller
rmuller

Reputation: 12859

We use or own simple method (Java 7+):

/**
 * Return the java {@link java.lang.Class} object with the specified class name.
 *
 * This is an "extended" {@link java.lang.Class#forName(java.lang.String) } operation.
 *
 * + It is able to return Class objects for primitive types
 * + Classes in name space `java.lang` do not need the fully qualified name
 * + It does not throw a checked Exception
 *
 * @param className The class name, never `null`
 *
 * @throws IllegalArgumentException if no class can be loaded
 */
public static Class<?> parseType(final String className) {
    switch (className) {
        case "boolean":
            return boolean.class;
        case "byte":
            return byte.class;
        case "short":
            return short.class;
        case "int":
            return int.class;
        case "long":
            return long.class;
        case "float":
            return float.class;
        case "double":
            return double.class;
        case "char":
            return char.class;
        case "void":
            return void.class;
        default:
            String fqn = className.contains(".") ? className : "java.lang.".concat(className);
            try {
                return Class.forName(fqn);
            } catch (ClassNotFoundException ex) {
                throw new IllegalArgumentException("Class not found: " + fqn);
            }
    }
}

Upvotes: 7

brafdlog
brafdlog

Reputation: 2692

Try ApacheCommons ClassUtils like this:

ClassUtils.getClass(className)

Works for primitives nicely.

The full name for the class is org.apache.commons.lang3.ClassUtils

Upvotes: 4

Bozho
Bozho

Reputation: 597076

You can't, because primitives are not objects.

What you are trying currently though is not yet instantiation - it is loading a class. But you can't do that for primitives. int is indeed the name that is used for int types, whenever their Class object is obtained (via reflection, for example method.getReturnType()), but you can't load it with forName().

Reference: Reflection tutorial:

If the fully-qualified name of a class is available, it is possible to get the corresponding Class using the static method Class.forName(). This cannot be used for primitive types

A solution to instantiate a primitive is to use commons-lang ClassUtils, which can get the wrapper class corresponding to a given primitive:

if (clazz.isPrimitive() {
    clazz = ClassUtils.primitiveToWrapper(clazz);
}
clazz.newInstance();

Note that this assumes you have the Class representing the int type - either via reflection, or via the literal (int.class). But it is beyond me what would be the usecase of having a string representation of that. You can use forName("java.lang.Integer") instead.

Upvotes: 22

Andrew White
Andrew White

Reputation: 53496

In this case, the best you can hope for is to create a map of primitives to their Autoboxed equivalent and return a class of that type.

Upvotes: 1

Related Questions