作用
学习如何获取类的信息,操作它们
获取class对象的三种方法
package com.zz.reflection;
import com.zz.Interface.studentMannger.ClassManager;
//目标:获取class对象
public class Test1Class {
public static void main(String args[]) throws ClassNotFoundException {
Class c1 = Student.class;//获取Class对象 --字节码
System.out.println(c1.getName());//全类名
System.out.println(c1.getSimpleName());//简名:Student
Class c2 = Class.forName("com.zz.reflection.Student");
System.out.println(c2 == c1);
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c3 == c2);
}
}
获取类的构造器,并对其操作
package com.zz.reflection;
import com.zz.Interface.studentMannger.ClassManager;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.sql.Connection;
/**
* 目标:掌握获取类的构造器,并对其进行操作
*/
public class Test2Constructor {
@Test
public void testGetConstructors() {
//1.反射第一步:必须先得到这个类的Class对象
Class c = Student.class;
//2.获取类的全部构造器
// Constructor[] constructors = c.getConstructors();只能获取public修饰的构造器
Constructor[] constructors = c.getDeclaredConstructors();//获取全部构造器--推荐
//3.遍历数组中的每个构造器对选哪个
for (Constructor constructor : constructors) {
System.out.println(constructor.getName() + "===>" + constructor.getParameterCount());
}
}
@Test
public void testGetConstructor() throws Exception {
//1.反射第一步:必须先得到这个类的Class对象
Class c = Student.class;
//2.获取某个构造器,无参构造器--
// Constructor constructor = c.getConstructor();只能取到public修饰的构造器
Constructor constructor = c.getDeclaredConstructor();//可以取到任意修饰符修饰的构造器
System.out.println(constructor.getName() + "==>" + constructor.getParameterCount());
constructor.setAccessible(true);//禁止检查访问权限
//初始化对象
Student student = (Student)constructor.newInstance();
System.out.println(student);
//3.获取有参数的构造器
Constructor constructor2 = c.getDeclaredConstructor(String.class, int.class);
System.out.println(constructor2.getName() + "==>" + constructor2.getParameterCount());
Student student1 = (Student)constructor2.newInstance("小明", 3);
System.out.println(student1);
}
}
获取类的成员变量
package com.zz.reflection;
import com.zz.Interface.studentMannger.ClassManager;
import org.junit.Test;
import java.lang.reflect.Field;
/**
* 目标:获取类的成员变量,并对其操作
*/
public class Test3Field {
@Test
public void testGetFields() throws NoSuchFieldException, IllegalAccessException {
//1.反射第一步,必须是先得到类的Class对象
Class s = Student.class;
//2.获取类的全部成员变量
Field[] fields = s.getDeclaredFields();
//3.遍历这个成员变量数组
for (Field field : fields) {
System.out.println(field.getName() + "==>" + field.getType());
}
//4.定位某个成员变量
Field fName = s.getDeclaredField("name");
System.out.println(fName.getName() + "===>" + fName.getType());
//赋值
Student student = new Student();
fName.setAccessible(true);//禁止访问控制权限
fName.set(student, "小红");
System.out.println(student);
//取值
String name = (String)fName.get(student);
System.out.println(name);
}
}
获取成员方法
package com.zz.reflection;
import org.junit.Test;
import java.lang.reflect.Method;
public class Test4Method {
@Test
public void testGetMethods() throws Exception {
//1.反射第一步,先得到Class对象
Class c = Cat.class;
//2.获取类的全部成员方法
Method[] methods = c.getDeclaredMethods();
//3.遍历这个数组中的每个方法对象
for (Method method : methods) {
System.out.println(method.getName() + "==>" + method.getParameterCount()
+ "===>" + method.getReturnType());
}
//4.获取某个方法对象
Method run = c.getDeclaredMethod("run");//无参数的
System.out.println(run.getName() + "->" + run.getParameterCount() + "->" +run.getReturnType());
Method eat = c.getDeclaredMethod("eat", String.class);
System.out.println(eat.getName() + "->" + eat.getReturnType());
Cat cat = new Cat();
run.setAccessible(true);
Object rs = run.invoke(cat);//调用无参数的run方法,用cat对象触发调用的
System.out.println(rs);
eat.setAccessible(true);
String rs2 = (String)eat.invoke(cat, "鱼儿");
System.out.println(rs2);
}
}
应用场景
案例
package com.zz.reflection;
//目标:使用反射技术,设计一个保存对象的简易版框架
import org.junit.Test;
public class Test5Frame {
@Test
public void save() throws Exception {
Student s1 = new Student("tom", 12, '男', 127.3, "打球");
Teacher t1 = new Teacher("李老师", 4567);
//需求:把任意对象的字段名和对应的值等信息,
ObjectFrame.saveObject(s1);
ObjectFrame.saveObject(t1);
}
}
package com.zz.reflection;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class ObjectFrame {
//目标:保存任意对象的字段和其数据到文件中去
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("data.txt",true));
//obj是任意对象
Class c = obj.getClass();
String cName = c.getSimpleName();
ps.println("===========" + cName + "=========");
//2.从这个类中提取它的全部成员变量
Field[] fields = c.getDeclaredFields();
//3.遍历每个成员变量
for (Field field : fields) {
//拿到成员变量的名字
String name = field.getName();
//5.拿到这个成员变量在对象中的数据
field.setAccessible(true);
String value = (String)(field.get(obj) + "");
ps.println(name + "=" + value);
}
ps.close();
}
}