概述:
Java反射机制:是指在运行时去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,
通过获取到的信息来创建对象,调用方法一种机制。由于这种动态性,可以极大的增强程序的灵活性,
程序不用在编译期就完成确定,在运行期仍然可以扩展。
获取Class类的对象:
要想通过反射区使用一个类,首先要获取该类的字节码文件对象,也就是类型为Class类型的对象,
这里java为我们提供了三种方式获取Class类型的对象。
1:使用类的class属性来获取该类对应的Class对象。
例:Student.class将会放回Student类对应的Class对象
2:调用对象的getClass()方法,返回该对象所属类对应的Class对象
该方法时Object类中的方法,所有Java对象都可以调用该方法
3:使用Class类中的静态方法forName(String className),
该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,
也就是完整包名的路径
获取构造方法并使用:
Class类中用于获取构造方法的方法
1,Constructor<?>[] getConstructors():返回所有公共构造方法对象的数组
2,Constructor<?>[] getDeclaredConstructors():返回所有构造方法对象的数组
3,Constructor<?> getConstructors(Class<?> ...partameter):返回单个公共构造方法对象
4,Constructor<?> getDeclaredConstructor(Class<?> ...partameter):返回单个构造方法对象
注:基础数据类型也可以通过.class得到对应Class类型
Constructor类中用于创建对象的方法
1,T newInstance(Object...initargs):根据指定的构造方法创建对象
注:当通过私有的构造方法进行反射创建对象时,会报错: class com.ReflectTest03
cannot access a member of class pojo.Student with modifiers "private",这里需要使用
public void setAccessible(boolean flag):设置值为true,取消访问检查,进行暴力反射
获取成员变量并使用:
Class类中用于获取成员变量的方法
1,Field[] getFields():返回所有公共成员变量对象的数组
2,Field[] getDeclaredFields():返回所有成员变量对象的数组
3,Field[] getField():返回单个公共成员变量对象
4,Field[] getDeclaredField():返回单个成员变量对象
Field类中用于给成员变量赋值的方法
1,void set(Object obj,Object value):给obj对象的成员变量赋值为value
获取成员方法并使用:
Class类中用于获取成员方法的方法
1,Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
2,Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
3,Method[] getMethod(String name,Class<?>...parameterTypes):返回单个公共成员方法对象
4,Method[] getDeclaredMethod(String name,Class<?>...parameterTypes):返回单个成员方法对象
Method类中用于调用成员方法的方法
1,Object invoke(Object obj,Object...args):调用obj对象的成员方法,参数时args,返回值时Object类型
代码案例:
package pojo;
public class Student {
//私有-成员变量
private String name;
//默认(default范围:同一个包,同一个类)-成员变量
Integer age;
//公共-成员变量
public Integer sex;
//公共-构造方法
public Student() {
}
//私有-构造方法
private Student(String name) {
this.name = name;
}
//默认-构造方法
Student(String name, Integer age) {
this.name = name;
this.age = age;
}
//公共-构造方法
public Student(String name, Integer age, Integer sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//私有-成员方法
private void function(){
System.out.println("function 私有-成员方法");
}
//公共-成员方法
public void method1(){
System.out.println("method1 公共-成员方法");
}
//公共-成员方法,有参数
public void method2(String s){
System.out.println("method1 公共-成员方法,有参" + s);
}
//公共-成员方法,有参数,有返回值
public String method3(String s,int i){
return s + "," + i;
}
//公共-toString方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
package com;
import pojo.Student;
//通过反射获取Class对象
public class ReflectTest00 {
public static void main(String[] args) throws ClassNotFoundException {
//方法一:使用类的class属性来获取该类对应的Class对象。
Class<Student> c1 = Student.class; //最为便捷简单
System.out.println(c1);
Class<Student> c2 = Student.class;
System.out.println(c1 == c2);
//方法二:调用对象的getClass()方法,返回该对象所属类对应的Class对象
Student s = new Student();
Class<? extends Student> c3 = s.getClass();
System.out.println(c1 == c3);
//方法三:使用Class类中的静态方法forName(String className)
Class<?> c4 = Class.forName("pojo.Student"); //可以使用配置文件配置
System.out.println(c1 == c4);
}
}
package com;
import pojo.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//通过反射获取Class对象的构造方法
public class ReflectTest01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//Constructor<?>[] getConstructors()
//返回一个包含Constructor对象的数组,Constructor对象反应了由该Class对象表示的类的所有公共构造函数
Constructor<?>[] cons1 = c.getConstructors();
//遍历公共的构造方法
for (Constructor<?> con : cons1) {
// System.out.println(con);
}
//Constructor<?>[] getDeclaredConstructors()
//返回反映由该Class对象表示的类声明的所有构造函数的Constructor对象数组
Constructor<?>[] cons2 = c.getDeclaredConstructors();
//遍历所有构造方法
for (Constructor<?> con : cons2) {
// System.out.println(con);
}
//Constructor<?> getConstructor(Class<?>...parameterTypes)
//返回一个Constructor对象,该对象反映由该Class对象表示的类指定公共构造函数
Constructor<?> con1 = c.getConstructor();
//打印公共的无参构造方法
// System.out.println(con1);
//Constructor<?> getDeclaredConstructor()
//返回一个Constructor对象,该对象反映由该Class对象表示的类或接口指定构造函数
//getConstructor 和 getDeclaredConstructor参数:
// 要获取的构造方法的参数的个数和数据类型对应的字节码文件对象
Constructor<?> con2 = c.getDeclaredConstructor(String.class);
//打印私有的构造方法
// System.out.println(con2);
//Constructor提供了一个类的单个构造函数的信息和访问权限
//T newInstance(Object... initargs)
//使用由此Constructor对象表示的构造函数,
// 使用指定的初始化参数来创建和初始化构造函数的声明类的新实例
Object o = con1.newInstance();
//通过反射获得Student类,而不是通过new的方式
System.out.println(o);
//使用反射实现等同于下面
// Student stu = new Student();
// System.out.println(stu);
}
}
package com;
import pojo.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//通过反射获取Class对象的构造方法——练习1
public class ReflectTest02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//基本数据类型也可以通过 .class得到对应的class类型
Constructor<?> cons = c.getConstructor(String.class, Integer.class, Integer.class);
//这里需要传入有参构造的对应参数
Object o = cons.newInstance("付修立",24,1);
//打印使用反射通过有参构造获取的学生类
System.out.println(o);
//使用反射实现等同于下面
// Student stu = new Student("付修立",24,1);
// System.out.println(stu);
}
}
package com;
import pojo.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//通过反射获取Class对象的构造方法——练习2
public class ReflectTest03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//获取构造方法
Constructor<?> cons = c.getDeclaredConstructor(String.class);
//暴力反射
// void setAccessible(boolean flag)
// 将此反射对象的accessible标志设置为指示的布尔值
cons.setAccessible(true); //值为true,取消访问检查
//这里会报错,需要进行暴力反射
//class com.ReflectTest03 cannot access a member of class pojo.Student with modifiers "private"
Object o = cons.newInstance("付修立");
System.out.println(o);
}
}
package com;
import pojo.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
//通过反射获取Class对象的成员变量
public class ReflectTest04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//Field[] getFields()
// 返回一个包含Field对象的数组,
// Field对象反映由该Class对象表示的类或接口的所有可访问的公共字段
Field[] fields = c.getFields();
for (Field field : fields) {
// System.out.println(field);
}
//Field[] getDeclaredFields()
// 返回一个Field对象的数组,
// 反映了由该Class对象表示的类或接口声明的所有字段
Field[] declaredFields = c.getDeclaredFields();
for (Field declaredField : declaredFields) {
// System.out.println(declaredField);
}
//Field[] getField(String name)
// 返回一个Field对象,
// 该对象反映由该class 对象表示的类或接口的指定公共成员字段
Field sex = c.getField("sex");
//通过无参构造方法构建对象
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
// o.address = 1;
//Field提供有关类或接口的单个字段的信息和动态访问
//void set(Object obj,Object value)
//将指定的对象参数中由此 Field对象标识的字段设置为指定的新值
sex.set(obj,1); //给obj对象的成员变量sex赋值为1
System.out.println(obj);
//Field[] getDeclaredField(String name)
// 返回一个Field对象,
// 该对象反映由该class 对象表示的类或接口的指定声明字段
//使用反射实现等同于下面
// Student s = new Student();
// s.sex = 1;
// System.out.println(s);
}
}
package com;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
//通过反射获取Class对象的成员变量——练习1
public class ReflectTest05 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//通过无参构造方法构建对象
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
System.out.println(obj);
//获取成员变量——name
Field name = c.getDeclaredField("name");
//设置为true,取消访问检查
name.setAccessible(true);
name.set(obj,"付修立");
System.out.println(obj);
//获取成员变量——age
Field age = c.getDeclaredField("age");
//设置为true,取消访问检查
age.setAccessible(true);
age.set(obj,24);
System.out.println(obj);
//获取成员变量——sex
Field sex = c.getDeclaredField("sex");
//设置为true,取消访问检查
sex.setAccessible(true);
sex.set(obj,1);
System.out.println(obj);
}
}
package com;
import pojo.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//通过反射获取Class对象的成员方法
public class ReflectTest06 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//Method[] getMethods()
//返回一个包含方法对象的数组,
//方法对象反映由该Class对象标识的类或接口的所有公共方法
//包括由类或接口声明的对象以及从超类中超级接口继承的类
Method[] methods = c.getMethods();
//所有的公共的方法,包括继承的
for (Method method : methods) {
// System.out.println(method);
}
//Method[] getDeclaredMethods()
//返回一个包含方法对象的数组,
// 方法对象反映由Class对象表示的类或接口的所有声明方法
// 包括public,protected,default,访问和私有方法,但不包括继承方法
Method[] declaredMethods = c.getDeclaredMethods();
//所有的方法,不包括继承的
for (Method declaredMethod : declaredMethods) {
// System.out.println(declaredMethod);
}
//Method[] getMethod(String name,Class<?>...parameterTypes)
//返回一个方法对象,
// 该对象反映由该Class对象标识的类或接口的指定公共成员方法
Method method1 = c.getMethod("method1");
//通过无参构造方法创建对象
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
// obj.method1()
//在类或者接口上提供有关单一方法的信息和访问权限
//Object invoke(Object obj,Object...args)
//在具有指定参数的指定对象上调用此方法表示基础方法
//Object:返回值类型
//obj:调用方法的对象
//args:方法需要的参数
method1.invoke(obj);
//Method[] getDeclaredMethod(String name,Class<?>...parameterTypes)
//返回一个方法对象,
// 该对象反映表示的类或接口的指定声明的方法CLass对象
//使用反射实现等同于下面
// Student s = new Student();
// s.method1();
}
}
package com;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//通过反射获取Class对象的成员方法——练习1
public class ReflectTest07 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//获取class对象
Class<?> c = Class.forName("pojo.Student");
//Student s = new Student();
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
//s.methodl
Method method1 = c.getMethod("method1");
method1.invoke(obj);
//s.method2("付修理")
Method method2 = c.getMethod("method2",String.class);
method2.invoke(obj,"付修立");
//String str = s.method3(24)
Method method3 = c.getMethod("method3", String.class, int.class);
Object object = method3.invoke(obj, "付修立", 24);
System.out.println(object);
//s.function()
Method function = c.getDeclaredMethod("function");
function.setAccessible(true);
function.invoke(obj);
}
}
本文只是个人学习内容整理的笔记,如有侵权,即联系870013269@qq.com删除