我的java 反射笔记
一、反射概念:
1、一定是在运行状态中进行的
2、对于任意一个实体类,都能够知道这个类的所有属性和方法
3、对于任意一个对象,都能够调用它的任意方法和属性
4、这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
二、利用反射我们能干什么
1、在运行时判断任意一个对象所属的类
2、在运行时构造任意一个类的对象
3、在运行时判断任意一个类所具有的成员变量和方法
4、在运行时调用任意一个对象的方法
5、生成动态代理
三、获取class对象
1、Class.forname(全类名) (带异常处理 推荐使用)
//获取该对象的class
Class c3 = null;
try {
c3 = Class.forName("com.test.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//打印获取的类名称
System.out.println("类名称:"+c3.getName());
2、类名.Class
/获取该对象的class
Class c2 = Person.class;
//打印获取的类名称
System.out.println("类名称:"+c2.getName());
3、对象.getclass()
//获取该对象的class
Class c1 = person.getClass();
//打印获取的类名称
System.out.println("类名称:"+c1.getName());
注意凡是反射必须是Class
四、反射获取构造方法
1、第一步获取反射接口即Class
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、通过Class获取构造方法
//2、获取构造方法
// 1)获取所有的公共方法 本类以及父类中以及接口中所有的方法,2.符合访问修饰符规律 public的方法 private不行
Constructor[] constructors = stuClass.getConstructors();
for (Constructor constructor : constructors ) {
System.out.println("获取所有public的构造方法:" + constructor);
}
// 2)获取当前类的所有构造方法(1.忽略访问修饰符规律 2.只限当前类)
Constructor[] constructors = stuClass.getDeclaredConstructors();
for (Constructor constructor : constructors ) {
System.out.println("获取当前类所有的构造方法:" + constructor);
}
五、反射获取方法
1、第一步获取反射接口即Class
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、第二步通过Class获取方法
获取方法的方式分为两种
①获取所有的公共方法 本类以及父类中以及接口中所有的公共方法,符合访问修饰符规律 public的 方法 private不行。
②获取当前类的所有方法(1.忽略访问修饰符规律 2.只限当前类,不含父类)
//2、获取方法
// 1)获取所有的公共方法 本类以及父类中以及接口中所有的方法,2.符合访问修饰符规律 public的方法 private不行
Method[] methods = stuClass.getMethods();
for (Method method : methods) {
System.out.println("获取所有的方法:" + method);
}
// 2)获取当前类的所有方法(1.忽略访问修饰符规律 2.只限当前类)
Method[] methods1 = stuClass.getDeclaredMethods();
for (Method method : methods1) {
System.out.println("获取当前类的方法:" + method);
}
六、反射获取属性
获取反射的属性也分两种方法
①所有的公共属性 本类及其父类中的
②本类中的属性
//2、获取属性
// 1)所有的公共属性 本类及其父类中的
Field[] fields = stuClass.getFields();
for (Field field : fields) {
System.out.println("所有的公共public属性:" + field);
}
// 2)本类中的属性
Field[] fields1 = stuClass.getDeclaredFields();
for (Field field : fields1) {
System.out.println("本类中的属性:" + field);
七、反射操作属性
方法一:
1、首先获取Class对象
2、在获取Object对象
3、在Object对象转为实例
4、设置实例的属性
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//方法一
// 1)获取对象
Object instance = null;
try {
instance = stuClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//2)、转化为实例
Student stud = (Student)instance;
//3)、设置实例的属性
stud.setStuNum("10001");
stud.setName("张三");
System.out.println("1、重新设置的属性 姓名:"+stud.getName()+" 学号:"+stud.getStuNum());
方法二:
1、首先获取Class对象
2、反射获取属性
3、反射方法设置属性值
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Field stuNumField = null;
Field stuClassNameField = null;
Field stuGradeField = null;
try {
//2、反射获取属性
stuNumField = stuClass.getDeclaredField("stuNum"); // private 属性
stuClassNameField = stuClass.getDeclaredField("className"); // private 属性
stuGradeField = stuClass.getDeclaredField("grade"); // public 属性
//操作私有属性 stuNumField.setAccessible(true);把私有属性设置为可以操作
stuNumField.setAccessible(true);
stuClassNameField.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
try {
//3、给属性赋值 给stud实例的 StuNum属性赋值,前面是实例,后面“1002”为参数
stuNumField.set(stud,"10002"); //相当于stud.setStuNum("10002");
stuClassNameField.set(stud,"计算机班");
stuGradeField.set(stud,"一年级");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("2、重新设置的属性 班级:"+stud.getClassName()+" 学号:"+stud.getStuNum()+" 年级:"+stud.getGrade());
注意:操作私有属性 setAccessible 方法一定要 设置 为true, public属性则不需 否则报错