通过反射构造对象
有了Class对象就可以创建这个类的对象了,反射机制中有两种构造对象的方法:Class类.newInstance()和构造器.newInstance(参数)。前者调用的是无参构造器,后者调用的是有参构造器,参数是有参构造器需要的参数。
@Testpublic void test() {User user = null;try {user = User.class.newInstance();} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();}System.out.println(user);}

@Testpublic void test() {try {Constructor<User> constructor=User.class.getConstructor(Integer.class,String.class,String.class);User user = constructor.newInstance(6, "阿离", "123456");System.out.println(user);} catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {e.printStackTrace();}}

如果使用反射来创建数组,那么参数依次需要数组类型和数组长度,Class类则是Array类:
@Testpublic void test() throws ClassNotFoundException {Class<?> clazz = Class.forName("java.lang.String");Object array = Array.newInstance(clazz, 25);//往数组里添加内容Array.set(array, 0, "Scala");Array.set(array, 1, "Java");Array.set(array, 2, "Groovy");Array.set(array, 3, "Scala");Array.set(array, 4, "Clojure");//获取某一项的内容System.out.println(Array.get(array, 3));}
通过反射调用方法
Class类除了可以创建对象,还可以调用指定的方法:可以先通过Class类的getDeclaredMethod方法获取指定的方法,并设置需要的参数,然后使用invoke方法进行激活该方法,并向该方法中传递要设置的obj对象的参数。Method类的invoke方法的语法:“方法(Method).invoke(Object obj , Object[] args)”。如果调用的方法是静态方法,那么obj设置为null;如果没有方法参数,则args设置为null。
如果调用的Method是private修饰的,在使用invoke方法之前必须先调用setAccessible方法,除了是设置访问权限,还关闭了安全检查(Java语言是安全的,这是因为它在编译和加载时都会进行安全检查。每次都进行检查,就像我们每次做事前都要准备一下,这样势必会降低我们的执行效率,因此这也是Java程序运行起来相比较C和C++慢的原因),如:
public static void test02() throws Exception{User user = new User(1,"阿狸","123654");Class<? extends User> clazz = user.getClass();Method method = clazz.getDeclaredMethod("getName", null);method.setAccessible(true);Object result = method.invoke(user, null);System.out.println(result);}

注意这里的Method类如果是public修饰的,调用setAccessible(true)只是取消安全检查,设置为false依然可以访问,取消安全检查的目的是为了提高反射效率。
通过反射调用属性
Class类可以调用对象的属性:先通过getDeclaredField获取对象的属性,然后如果调用的属性是private的话,就需要使用setAccessible方法(参数设置为true)来获取权限(使用setAccessible方法还可以提高反射的运行速率)。
语法:使用“属性(Field).set(对象obj,“属性值”)”来改变属性值;使用“属性(Field).get(对象obj)”来访问属性。
通常的po类对象都是有getXxx、setXxx方法的,可以通过getXxx、setXxx访问属性,但是如果没有这些方法,就可以使用反射来访问类的属性了。
@Test
public void test() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
User user = new User(1, "阿离", "123654");
Class<? extends User> clazz = user.getClass();
Field field=clazz.getDeclaredField("name");
field.setAccessible(true);
field.set(user,"小阿狸");
Object result = field.get(user);
System.out.println(result);
}

如果访问的是private属性,并且不调用setAccessible(true)则会抛出异常:
