java反射 reflex 反射获取方法 反射获取属性
一、反射概念:
1、一定是在运行状态中进行的
2、对于任意一个实体类,都能够知道这个类的所有属性和方法
3、对于任意一个对象,都能够调用它的任意方法和属性
这种动态获取信息以及动态调用对象方法的功能称为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、第一步获取反射接口
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、获取方法
分2种
①获取所有的公共方法 本类以及父类中以及接口中所有的公共方法,符合访问修饰符规律 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、首先,依旧要获取class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、反射获取属性
也分2种
①所有的公共属性 本类及其父类中的
②本类中的属性
//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 属性
//操作私有属性 一定要 设置 为true public属性则不需 否则报错
stuNumField.setAccessible(true);
stuClassNameField.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
try {
//3、给属性赋值
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属性则不需 否则报错
七、反射操作实例的方法
步骤:
1、先获取反射的Class
2、获取需要操作的方法
setAccessible 设置为可利用 不然会报错,public方法则不需
4、获取实例对象
5、调用该方法
给大佬奉茶:
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method method = null;
try {
//2、获取方法
method = stuClass.getDeclaredMethod("setStuNum",String.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
//3、设置为可利用 不然会报错
method.setAccessible(true);
Student person = null;//将instance转化为Person
try {
//4、获取实例对象
person = (Student)stuClass.newInstance();
//5、调用该方法
method.invoke(person,"10003");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}catch (InvocationTargetException e) {
e.printStackTrace();
}
八、反射操作构造方法(构造方法分public和 private)
步骤:
1、先获取反射的Class
2、获取需要构造方法(分无参数和有参数 2种)
3、调用构造方法(无参数和有参数 2种)
上代码:
//1、先获取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取全部公共构造方法 public
Constructor<?>[] constructors = stuClass.getConstructors();
for (Constructor constructor:constructors) {
System.out.println("全部公共构造方法"+constructor);
}
//2、获取本类的公共构造方法
Constructor<?>[] constructors02 = stuClass.getDeclaredConstructors();
for (Constructor constructor:constructors02) {
System.out.println("本类构造方法" + constructor);
}
try {
//3-1获取指定 无参数的构造方法
Constructor<?> constructor02 = stuClass.getConstructor();
Student stud = null;
try {
//如果构造函数是private 一定要加入下面这句话 否则报错
//constructor02.setAccessible(true);
stud = (Student) constructor02.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("本类无参数构造方法的对象:"+stud);
//3-2获取指定 有参数的构造方法
Constructor<?> constructor03 = stuClass.getConstructor(String.class);
Student stud2 = null;//转化为Person类
try {
//如果构造函数是private 一定要加入下面这句话 否则报错
//constructor02.setAccessible(true);
constructor03.setAccessible(true);
//4 调用构造方法 传参
stud2 = (Student)constructor03.newInstance("10004");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("本类指定的有参数的构造方法的对象:"+stud2);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
九、使用反射给对象赋值通用方法
//动态给对象赋值
public void setProperty(Object obj, String propertyName, Object value) throws
NoSuchFieldException, IllegalAccessException {
Class<?> perclass = obj.getClass();
Field field = perclass.getDeclaredField( propertyName);//获得属性
field.setAccessible(true);//因为是私有的
field.set(obj,value);//(对象,方法)
}
调用
//使用反射给对象赋值通用方法
Student student = new Student();
try {
test.setProperty(student,"stuNum","10007");
System.out.println("动态设置的属性为:stuNum="+student.getStuNum());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}