mike_x_
mike_x_

Reputation: 1929

Dynamic object creation in java using reflection

What does Class[] null and Object[] null mean in the code below?

public Object selfFactory() {
    Class cl = this.getClass();
    Constructor cons;
    cons = cl.getConstructor((Class[]) null);
    return cons.newInstance((Object[]) null);
}

Upvotes: 0

Views: 383

Answers (1)

Unihedron
Unihedron

Reputation: 11041

cl.getConstructor((Class[]) null); takes the parameter for both its value and type as a type parameter <T>, so casting is necessary if we're supplying a null Class[] instead of a null Object for method invocation of .getConstructor().

Similarly, cons.newInstance((Object[]) null); creates a new instance of cl by invoking a constructor cons which takes an Object[], given as null in this case. Without the typecast, a null Object will be passed.

This is useful for when methods or constructors are overloaded. Invocation with null without cast will be of type Object and often ambiguous:

{
    eat(null); // ???
}

void eat(int[] arr);
void eat(Class arr);

With a cast, the correct constructor or method can be called.

{
    eat((Class) null);
}

Also as documented by polygenelubricants in How to work with varargs and reflection,

[...] invoke(Object obj, Object... args) makes it tricky if you need to pass an array of reference type as an only argument, because it is cast-able to Object[], even though it should be wrapped inside a new Object[1] instead.

You can do:

m.invoke(this, new Object[] {a}); // Bohzo's solution

This bypasses the vararg mechanism. More succinctly you can also do:

m.invoke(this, (Object) a);

The cast to Object makes the vararg mechanism do the work of creating the array for you.

The trick is also needed when passing a null as an argument to varargs, and has nothing to do with reflection.

public void foo(String... ss) {
    System.out.println(ss[0]);
}

    foo(null); // causes NullPointerException
    foo((String) null); // prints "null"

Upvotes: 5

Related Questions