通过反射创建新类示例的两种方式及比较
https://blog.csdn.net/fenglibing/article/details/4531033
通过反射创建新的类示例,有两种方式:
Class.newInstance()
Constructor.newInstance()
以下对两种调用方式给以比较说明:
l Class.newInstance() 只能够调用无参的构造函数,即默认的构造函数;而Constructor.newInstance() 可以根据传入的参数,调用任意构造构造函数。
l Class.newInstance() 抛出所有由被调用构造函数抛出的异常。
l Class.newInstance() 要求被调用的构造函数是可见的,也即必须是public类型的; Constructor.newInstance() 在特定的情况下,可以调用私有的构造函数。
package com.tmall.toosimple.algorithmprocess.impl.test; public class A { private A() { System.out.println("A' default constructor is call"); } private A(int a, int b) { System.out.println("a=" + a + ", b=" + b); } }
1 package com.tmall.toosimple.algorithmprocess.impl.test; 2 3 import java.lang.reflect.Constructor; 4 5 public class B { 6 7 public static void main(String[] args) { 8 B b = new B(); 9 b.newInstanceByConstructor(); 10 b.newInstanceByClass(); 11 } 12 13 14 private void newInstanceByClass() { 15 try { 16 A a = (A) Class.forName("com.tmall.toosimple.algorithmprocess.impl.test.A").newInstance(); 17 } catch (InstantiationException e) { 18 e.printStackTrace(); 19 } catch (IllegalAccessException e) { 20 e.printStackTrace(); 21 } catch (ClassNotFoundException e) { 22 e.printStackTrace(); 23 } 24 } 25 26 private void newInstanceByConstructor() { 27 try { 28 Class clazz = Class.forName("com.tmall.toosimple.algorithmprocess.impl.test.A"); 29 30 Constructor<?>[] constructors = clazz.getDeclaredConstructors(); 31 Constructor<?>[] constructors1 = clazz.getConstructors(); 32 33 Constructor constructor = clazz.getDeclaredConstructor(); 34 constructor.setAccessible(true); 35 A A0 = (A)constructor.newInstance(); 36 System.out.println(constructors1.length); 37 38 39 Constructor constructor1 = clazz.getDeclaredConstructor(new Class[]{int.class ,int.class }); 40 constructor1.setAccessible(true); 41 A A1 = (A)constructor1.newInstance(new Object[]{5, 6}); 42 43 } catch (Exception e) { 44 e.printStackTrace(); 45 } 46 } 47 }
结果输出:
A' default constructor is call
0
a=5, b=6
java.lang.IllegalAccessException: Class com.tmall.toosimple.algorithmprocess.impl.test.B can not access a member of class com.tmall.toosimple.algorithmprocess.impl.test.A with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
at java.lang.Class.newInstance(Class.java:436)
at com.tmall.toosimple.algorithmprocess.impl.test.B.newInstanceByClass(B.java:16)
at com.tmall.toosimple.algorithmprocess.impl.test.B.main(B.java:10)
//invoke示例
1 package com.tmall.toosimple.algorithmprocess.impl.test; 2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Method; 5 import org.junit.Test; 6 7 public class Msym { 8 public void test(String[] arg){ 9 for (String string : arg) { 10 System.out.println(string); 11 } 12 } 13 14 public void test1(String... args) { 15 for (String arg : args) { 16 System.out.println(arg); 17 } 18 } 19 20 21 @Test 22 public void demo1() throws Exception { 23 24 Msym msym = new Msym(); 25 msym.test1("a", "b"); 26 27 28 //获取字节码对象 29 Class<Msym> clazz = (Class<Msym>) Class.forName("com.tmall.toosimple.algorithmprocess.impl.test.Msym"); 30 //获取一个对象 31 Constructor con = clazz.getConstructor(); 32 Msym m = (Msym) con.newInstance(); 33 String[] s = new String[]{"aa","bb"}; 34 //获取Method对象 35 Method method = clazz.getMethod("test", String[].class); 36 //调用invoke方法来调用 37 method.invoke(m, new Object[]{s}); 38 method.invoke(m, (Object)s); 39 String[] s1 = new String[]{"cc", "dd"}; 40 method.invoke(m, (Object)(new String[]{"cc", "dd"})); 41 42 Object object = (Object)s1; 43 System.out.println("object=" + object.toString()); 44 } 45 }