HADOOP-17287. Support new Instance by non default constructor by ReflectionUtils (#2341)
This commit is contained in:
parent
a490d87eb7
commit
d68d2a5c1e
@ -124,15 +124,35 @@ private static void setJobConf(Object theObject, Configuration conf) {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newInstance(Class<T> theClass, Configuration conf) {
|
||||
return newInstance(theClass, conf, EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
/** Create an object for the given class and initialize it from conf
|
||||
*
|
||||
* @param theClass class of which an object is created
|
||||
* @param conf Configuration
|
||||
* @param argTypes the types of the arguments
|
||||
* @param values the values of the arguments
|
||||
* @return a new object
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newInstance(Class<T> theClass, Configuration conf,
|
||||
Class<?>[] argTypes, Object ... values) {
|
||||
T result;
|
||||
if (argTypes.length != values.length) {
|
||||
throw new IllegalArgumentException(argTypes.length
|
||||
+ " parameters are required but "
|
||||
+ values.length
|
||||
+ " arguments are provided");
|
||||
}
|
||||
try {
|
||||
Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(theClass);
|
||||
if (meth == null) {
|
||||
meth = theClass.getDeclaredConstructor(EMPTY_ARRAY);
|
||||
meth = theClass.getDeclaredConstructor(argTypes);
|
||||
meth.setAccessible(true);
|
||||
CONSTRUCTOR_CACHE.put(theClass, meth);
|
||||
}
|
||||
result = meth.newInstance();
|
||||
result = meth.newInstance(values);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.apache.hadoop.test.GenericTestUtils;
|
||||
import org.apache.hadoop.test.GenericTestUtils.LogCapturer;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -168,6 +169,34 @@ public void testLogThreadInfo() throws Exception {
|
||||
containsString("Process Thread Dump: " + title));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewInstanceForNonDefaultConstructor() {
|
||||
Object x = ReflectionUtils.newInstance(
|
||||
NoDefaultCtor.class, null, new Class[] {int.class}, 1);
|
||||
assertTrue(x instanceof NoDefaultCtor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewInstanceForNonDefaultConstructorWithException() {
|
||||
try {
|
||||
ReflectionUtils.newInstance(
|
||||
NoDefaultCtor.class, null, new Class[]{int.class}, 1, 2);
|
||||
fail("Should have failed before this point");
|
||||
} catch (IllegalArgumentException e) {
|
||||
GenericTestUtils.assertExceptionContains(
|
||||
"1 parameters are required but 2 arguments are provided", e);
|
||||
}
|
||||
|
||||
try {
|
||||
ReflectionUtils.newInstance(
|
||||
NoDefaultCtor.class, null, new Class[]{int.class});
|
||||
fail("Should have failed before this point");
|
||||
} catch (IllegalArgumentException e) {
|
||||
GenericTestUtils.assertExceptionContains(
|
||||
"1 parameters are required but 0 arguments are provided", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Used for testGetDeclaredFieldsIncludingInherited
|
||||
private class Parent {
|
||||
private int parentField;
|
||||
|
Loading…
Reference in New Issue
Block a user