一:了解
反射就是:加载类,并允许以编程的方式解刨类中的各种成分(成员变量、方法、构造器等)。
二:反射就是学习获取类的信息,操作它们
1.反射第一步:加载类,获取类的字节码:Class对象
2.获取类的构造器:Constructor对象
3.获取类的成员变量:Filed对象
4.获取类的成员方法:Methon对象
三:获取Class对象的三种方式
1.Class c = 类名.class;
2.调用Class提供的方法:public static Class forName(String package);
3.Object提供的方法:public Class getClass(); Class c = 对象.getClass();
4.示例:
public class Test1 {
public static void main(String[] args) throws Exception {
Class c1 = Student.class;
Class c2 = Class.forName("High.Student");
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c1.getName());//全类名
System.out.println(c1.getSimpleName());//简类名
}
}
四:获取类的构造器、并对其进行操作
1.Class提供了从类中获取构造器的方法
getConstructors() 获取全部构造器(只能获取public修饰的)
getDeclaredConstructors() 获取全部构造器(只要存在就能拿到)
getConstructor(Class<?>... parameterTypes) 获取某个构造器(只能获取public修饰的)
getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到)
2.获取类构造器的作用:依然是初始化对象返回
Constructor提供的方法
newInstance(Object... initargs) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)
3.示例:
import java.lang.reflect.Constructor;
public class Test2 {
public static void main(String[] args) throws Exception {
getConstructors();
getConstructor();
}
public static void getConstructors(){
//1.反射第一步必须先得到这个类的对象
Class s = Student.class;
// Constructor[] constructors = s.getConstructors();
Constructor[] constructors = s.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName()+"------->"+
constructor.getParameterCount());//获取参数的个数
}
}
public static void getConstructor() throws Exception {
Class s = Student.class;
// Constructor c1 = s.getConstructor();
Constructor c1 = s.getDeclaredConstructor();
c1.setAccessible(true);//禁止检查访问权限
Student ss1 = (Student) c1.newInstance();
System.out.println(c1.getName()+"-------->"+
c1.getParameterCount());
System.out.println(ss1);
// Constructor c2 = s.getConstructor(String.class, int.class);
Constructor c2 = s.getDeclaredConstructor(String.class, int.class);
c2.setAccessible(true);//禁止检查访问权限
Student ss2 = (Student) c2.newInstance("蔡建宇", 18);
System.out.println(c1.getName()+"-------->"+
c2.getParameterCount());
System.out.println(ss2);
}
}
五:获取类的成员变量
1.Class提供了从类中获取成员变量的方法
getFields() 获取类的全部成员变量(只能获取public修饰的)
getDeclareFields() 获取类的全部成员变量(只要存在就能拿到)
getField(String name) 获取类的某个成员变量(只能获取public修饰的)
getDeclareField(String name) 获取类的某个成员变量(只要存在就能拿到)
2.获取到成员变量的作用:依然是赋值,取值
set(Object obj, Object value) 赋值
get(Object obj) 取值
setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)
3.示例:
import java.lang.reflect.Field;
public class Test3 {
public static void main(String[] args) throws Exception {
getFields();
getField();
}
public static void getFields(){
Class s = Student.class;
Field[] fields = s.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName()+"----->"+
field.getType());
}
}
public static void getField() throws Exception {
Class s = Student.class;
Student ss = new Student();
Field Fname = s.getDeclaredField("name");
System.out.println(Fname.getName()+"----->"+
Fname.getType());
Fname.setAccessible(true);
Fname.set(ss,"王凯");
System.out.println(Fname.get(ss));
Field Fage = s.getDeclaredField("age");
System.out.println(Fage.getName()+"----->"+
Fage.getType());
Fage.setAccessible(true);
Fage.set(ss,18);
System.out.println(Fage.get(ss));
}
}
六:获取类的成员方法
1.Class提供了从类中获取成员方法的API
getMethods() 获取类的全部成员方法(只能获取public修饰的)
getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到)
getMethod(String name , Class<?>... parameterTypes) 获取类的某个成员方法(只能获取public修饰的)
getDeclaredMethod(String name , Class<?>... parameterTypes) 获取类的某个成员方法(只要存在就能拿到)
2.成员方法的作用:依然是执行
invoke(Object obj, Object... args) 触发某个对象的该方法执行
setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射)
3.示例:
import java.lang.reflect.Method;
public class Test4 {
public static void main(String[] args) throws Exception {
getMethods();
getMethod();
}
public static void getMethods(){
Class c = Student.class;
Method[] declaredMethods = c.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName()+"---->"+
declaredMethod.getParameterCount()+"----->"+
declaredMethod.getReturnType());
}
}
public static void getMethod() throws Exception {
Class c = Student.class;
Method study = c.getDeclaredMethod("Study");//调用无形参的
System.out.println(study.getName()+"---->"+
study.getParameterCount()+"---->"+
study.getReturnType());
Method eat = c.getDeclaredMethod("eat", String.class);//调用有形参的
System.out.println(eat.getName()+"---->"+
eat.getParameterCount()+"---->"+
eat.getReturnType());
Student s = new Student();
study.setAccessible(true);
study.invoke(s);
eat.setAccessible(true);
eat.invoke(s,"饭");
}
}
七:反射的作用
1.基本作用:可以得到一个类的全部成分,然后操作
2.可以破坏封装性
3.最重要的用途是:适合做Java框架,基本上,主流的框架都会基于反射设计出一些通用的功能
4.应用场景:对于任意一个对象,该框架都可以吧对象的字段名和对应的值,保存到文件中去。
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
public class JavaFrame {
public static void saveObject(Object obj) throws Exception {
PrintStream ps = new PrintStream(new FileOutputStream("D:\\练习\\TheLast\\src\\High\\data.txt",true));
Class c = obj.getClass();
String simpleName = c.getSimpleName();
ps.println("----------"+simpleName+"------------");
Field[] declaredFields = c.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
ps.println(declaredField.getName()+"--------->"+declaredField.get(obj));
}
ps.close();
}
}
public class Test5 {
public static void main(String[] args) throws Exception {
Student S = new Student("蔡建宇",18);
Teacher T = new Teacher("李鹤声","语文",54);
JavaFrame.saveObject(S);
JavaFrame.saveObject(T);
}
}