HADOOP-17287. Support new Instance by non default constructor by ReflectionUtils (#2341)

This commit is contained in:
maobaolong 2020-10-01 05:22:55 +08:00 committed by GitHub
parent a490d87eb7
commit d68d2a5c1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 2 deletions

View File

@ -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);
}

View File

@ -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;