Question

See Boolean#TYPE for an example of what I'm referring to.

All of the wrapper classes (Boolean, Double, Integer, etc) have a static Class field associated with them called TYPE. What is the meaning of this?

Specifically, here are a few soft tests:

System.out.println(Boolean.class == Boolean.TYPE);
System.out.println(Boolean.TYPE.isInstance(Boolean.valueOf(true)));

Both evaluate as false. (And as a side note, an .equals comparison is unnecessary since Class does not override equals from Object.)

Both Boolean.class and Boolean.TYPE are Class<Boolean> because they are == comparable without an error. Comparing two objects with differently declared generic types is illegal.

On further inspection, the TYPE fields are retrieved by calling a package-private native method Class#getPrimitiveClass along the lines of the following:

public static final Class<Boolean> TYPE = Class.getPrimitiveClass("boolean");

The comment on the method itself is not particularly informative either. It says it returns the VM's class object for the type which is fairly obvious since it is a native method.

I can't find any documentation on this beyond the Java docs' vague allusion to "representing the primitive type". Is there some kind of use for this field? It's unused in the wrapper classes themselves.

(Edited)

System.out.println(boolean.class == Boolean.TYPE);

Is true.

Also one use is then reflection:

try {
    Constructor ctor = Boolean.class.getConstructor(Boolean.class);
} catch (Exception e) {
    System.out.println("NoSuchMethodException gets thrown");
}

try {
    Constructor ctor = Boolean.class.getConstructor(Boolean.TYPE);
    System.out.println(ctor.newInstance(true));
} catch (Exception e) {
    // (no exception thrown)
}

And I've found some SO threads that cite that, such as this one. I guess I came from the "wrong end" of Google so-to-speak to not find any results on it.

But considering the existence of the "primitive classes" (boolean.class, int.class etc.) that doesn't really explain the TYPE field existence. Basically it's "just there"? I still don't really get it.

Was it helpful?

Solution

The class representing the primitive type is useful in specifying or examining methods that take or return primitives. For example, if your class has a method that looks like this

class Test {
    static int round(float val) {...}
}

and you wish to access this method through reflection, you would need to do this:

Method round = Test.class.getMethod("round", Float.TYPE);

You can examine the return type, too:

if (round.getReturnType == Integer.TYPE) {
    System.out.println("Method 'round' returns an int.");
}

Using Float.class instead

Method round = Test.class.getMethod("round", Float.class);

would not work, because that would pull a different method - this one:

static int round(Float val) {...}

OTHER TIPS

(Don't have the rep to comment, so must answer.)

To put it succinctly: Float.TYPE == float.class, and Float.class != float.class. Consider:

class Test {
    void func() {
        Class clazz;
        // The two statements do the same thing.  On my system, they even compile
        //   to the same bytecode.
        clazz = Integer.TYPE;    // explicitly asking for this
        clazz = int.class;       // must yield the same object as above.

        // Both of these below are valid, as the `true' is autoboxed.  In 
        //   Java < 1.5, both had to be explicitly boxed
        Test.class.getMethod("test", Boolean.class).invoke(this, true);
            // calls method A
        Test.class.getMethod("test", boolean.class).invoke(this, true);
            // calls method B.  Could also use getMethod("test", Boolean.TYPE) 
    }

    void test(Boolean b) { System.out.println("Method A"); }
    void test(boolean b) { System.out.println("Method B"); }
}

I would assume both int.class andInteger.TYPE have been around from the beginning of Java, though I may be wrong. Integer.TYPE can be initially assigned with Class.getPrimitiveClass("int").

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top