第一步为获取Class类的实例
获取Class类实例的方法有三种
1、类名.class
2、对象.getClass()
3、Class.forName("类的完全限定名"):我的类的完全限定名是com.test.dome5.Student
//类名.class
Class c1= Student.class;
//对象.getClass
Student student=new Student();
Class c2=student.getClass();
//Class.forName("完全限定的类名")
Class c3=Class.forName("com.test.dome5.Student");
//输出验证结果是否相等
System.out.println(c1==c2);
System.out.println(c3==c2);
运行之后输出结果相等,说明三个方法都是一样可以使用的
第二步通过Class获取构造方法、字段属性、方法、接口...
java.lang.Class | 代表整个字节码。代表一个类型,代表整个类 |
java.lang.reflect.Method | 代表字节码中的方法字节码。代表类中的方法 |
java.lang.reflect.Constructor | 代表字节码中的构造方法字节码。代表类中的构造方法 |
java.lang.reflect.Field | 代表字节码中的属性字节码。代表类中的成员变量(静态变量+实例变量) |
class类的方法:
方法名 | 备注 |
---|---|
public T newInstance() | 创建对象 |
public String getName() | 返回完整类名带包名 |
public String getSimpleName() | 返回类名 |
public Field[] getFields() | 返回类中public修饰的属性 |
public Field[] getDeclaredFields() | 返回类中所有的属性 |
public Field getDeclaredField(String name) | 根据属性名name获取指定的属性 |
public native int getModifiers() | 获取属性的修饰符列表,返回的修饰符是一个数字,每个数字是修饰符的代号【一般配合Modifier类的toString(int x)方法使用】 |
public Method[] getDeclaredMethods() | 返回类中所有的实例方法 |
public Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 根据方法名name和方法形参获取指定方法 |
public Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 根据方法名name和方法形参获取指定方法 |
public Constructor getDeclaredConstructor(Class<?>… parameterTypes) | 根据方法形参获取指定的构造方法 |
用反射操作所有构造方法:
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<String> cla= (Class<String>) Class.forName("com.test.dome1.Student");
Constructor<Student>[] crs1=(Constructor<Student>[]) cla.getConstructors();//得到所有构造方法
for (int i = 0; i < crs1.length; i++) {
System.out.println(crs1[i]);//遍历出构造方法
}
String str="123";
Student s1=crs1[0].newInstance(str);//newInstance创建对象
System.out.println(s1);
}
结果:
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<Student> cla=Student.class;
Constructor<Student> c1=cla.getConstructor();
Student s1=c1.newInstance();
Constructor<Student> c2=cla.getConstructor(String.class,int.class,String.class);
c2.setAccessible(true);
Student s2=c2.newInstance("张三",18,"男");
Constructor<Student> c3=cla.getDeclaredConstructor(String.class);
c3.setAccessible(true);
Student s3=c3.newInstance("李四");
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
结果:
通过反射操作字段:
public static void main(String[] args) throws NoSuchFieldException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<Student> clazz=Student.class;
Field field=clazz.getField("sex");//根据字符获取公共字段
System.out.println(field.getName());//获取字段名
field=clazz.getDeclaredField("name");//根据字段名获取字段
System.out.println(field.getModifiers());//修饰符 数字
System.out.println(field.getType());//类型
System.out.println(field.getGenericType());//泛型类型
//操作字段,需要有一个对象
//1、 先创建对象 2、获取字段 3、操作字段
Student obj = clazz.getConstructor().newInstance();
// Student obj=clazz.newInstance();
field.setAccessible(true);//允许访问私有属性
field.set(obj,"张三");//设置属性
String name=field.get(obj).toString();//获取某字段的属性值
System.out.println(name);
field=clazz.getField("sex");
field.set(obj, "男");
System.out.println(obj);
Field[] fields = clazz.getDeclaredFields();//获取所有字段
for (Field field1 : fields) {
System.out.println(field1.getName());
}
}
结果: