1、Java.lang.reflect库
Class类和java.lang.reflect类库一起对反射的概念进行支持。在java.lang包下:Class
2、通过反射实例化对象
(1)平常情况我们通过new Object来生成一个类的实例,但有时候我们没法直接new,只能通过反射动态生成。
(2)实例化无参构造函数的对象,两种方式:
Class.newInstace();
Class.getConstructor(new Class[]{}).newInstance(new Object[]{});
(3)实例化带参构造函数的对象
Class.getConstructor(Class<?>...parameterTypes).newInstance(Object...initargs);
3、通过反射获取并调用方法
(1)获得当前类以及超类的public Method
Method[] arrMethods=classType.getMethods();
(2)获得当前类申明的所有Method
Method[] arrMethods=classTyep.getDeclaredMethods();
(3)获得当前类以及超类指定的public Method
Method method=classType.getMethod(String name,Class<?>...parameterTypes);
(4)获得当前类申明的指定的Method
Method method=classType.getDeclaredMethod(String name,Class<?>...parameterTypes);
(5)通过反射动态运行指定Method
Object obj=method.invoke(Object obj,Object...args);
4、通过反射获取并调用属性
(1)获得当前类以及超类的public Field
Field[] arrFields=classType.getFields();
(2)获得当前类申明的所有Field
Field[] arrFields=classType.getDeclaredFields();
(3)获得当前类以及超类指定的public Field
Field field=classType.getField(String name);
(4)获得当前类申明的指定的Field
Field field=classType.getDeclaredField(String name);
(5)通过反射动态设定Field的值
field.set(Object obj,Object value);
(6)通过反射动态获取Field的值
Object obj=field.get(Object obj);
5、举例
package com.iotek.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionAPIDemo {
public static void main(String[] args) throws Exception{
/**
* 只要用到反射,先获得Class对象。没有方法能够获得当前类的超类的private方法和属性,
* 你必须通过getSuperclass()找到超类以后再去尝试获得。通常情况下,即使是当前类,
* private属性或者方法也是不能访问的,你需要设置压制权限setAccessible(true)来
* 取得private的访问权。但这样的话,就破坏了面向对象的规则,所以除非万不得已,尽量少用。
*/
//获取Emploee这个类所关联的class对象
Class<?> classType=Class.forName("com.iotek.reflect.Emploee");
//通过反射机制来构造一个Emploee的实例对象(默认调用无参的构造方法)
Emploee emploee=(Emploee)classType.newInstance();
//调用指定的构造方法来实例化对象
Constructor<?> constructor=classType.getConstructor(new Class[]{});
Emploee emploee2=(Emploee)constructor.newInstance(new Object[]{});
System.out.println(emploee);
System.out.println(emploee2);
//调用指定的构造方法来实例化对象(调用带参数的构造方法)
Constructor<?> constructor1=classType.getConstructor(new Class[]{String.class,int.class});
Emploee emploee3=(Emploee)constructor1.newInstance(new Object[]{"zhangsan",30});
System.out.println(emploee3);
//获取class对象指定的方法,包括私有的
Method method=classType.getDeclaredMethod("toString", new Class[]{});
System.out.println(method.getName());
//方法的调用
String desc=(String) method.invoke(emploee, new Object[]{});
System.out.println(desc);
//获取class对象指定的所有方法,包括私有的(私有的是默认不能被访问的)
Method[] methods = classType.getDeclaredMethods();
for(Method method2 : methods){
method2.setAccessible(true);//私有的可以访问了
System.out.println(method2.getName()+"-->"+method2.getModifiers());
}
//获取Class对象所指定的属性,包括私有的(私有的默认是不能被访问的)
Field field = classType.getDeclaredField("nameString");
field.setAccessible(true);//可访问了
field.set(emploee, "李四");
System.out.println(field.get(emploee));
}
}
class Emploee{
private String nameString;
private int age;
public Emploee(){
System.out.println("无参构造法方法");
}
public Emploee(String nameString, int age) {
super();
this.nameString = nameString;
this.age = age;
}
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Emploee [nameString=" + nameString + ", age=" + age + "]";
}
}
6、使用反射机制来创建一维数组和二维数组
package com.iotek.reflect;
import java.lang.reflect.Array;
public class ReflectionArrayDemo {
public static void main(String[] args) throws ClassNotFoundException {
//创建一个一维数组(String)
Class<?> classType = Class.forName("java.lang.String");
Object obj = Array.newInstance(classType,5);
Array.set(obj, 3, "abc");
System.out.println(Array.get(obj, 3));
//创建二维数组(3行3列)
int[] dimens={3,3};
Object obj1 = Array.newInstance(int.class, dimens);
Object obj2 = Array.get(obj1, 2);//获取第三行(它是一个一维数组)
Array.setInt(obj2, 2, 5);//给指定位置赋值
int[][] obj3 = (int[][])obj1;
System.out.println(obj3[2][2]);
}
}