反射的基础-常用的方法
首先看下Class类:
1:这个Class类的父类还是Object类,这个类也是一个最终类,Class类没有公共构造方法,Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的。这个Class对象是由java虚拟机来创建的。
2:常用的方法有哪些:怎样通过反射来获取一个类中的信息。
2.1、要想获取到类中的信息,必须得到Class对象
获取Class的对象有几种方式:
A:通过本身的class属性获取:
System.out.println(StudentDemo.class);
B:通过类对应实例获取(自动补全:CTRL+2,l)
StudentDemo studentDemo1 = new StudentDemo();
System.out.println(studentDemo1.getClass());
C : 通过Class类中提供的静态forName方法获取
Class clazz=Class.forName("com.weizhaoyang.Student.StudentDemo");
System.out.println(clazz);
2.2、获取一个Class对象中的成员变量:
A、 获取所有的由public修饰的成员变量,代码如下:
Class clazz = StudentDemo.class;
// 获取所有的由public修饰的成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
运行的结果如下:public:访问修饰符,java.lang.String:字段类型
com.weizhaoyang.Student.StudentDemo.cats:字段名称
B、获取当前Class对应类中所有定义的成员变量,代码如下:
fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
System.out.println("访问修饰符:" + Modifier.toString(field.getModifiers()));
System.out.println("字段类型:" + field.getType().getTypeName());
System.out.println("字段类型简单名称:" + field.getType().getSimpleName());
System.out.println("字段名称:" + field.getName());
}
运行的结果如下:
C、如何获取一个私有的字段从而给设置值:
// 通过Class对象创建类实例
Object instance = clazz.newInstance(); // Object stu = new Student();
// 单独获取一个字段
Field field = clazz.getDeclaredField("age");
// 开启任何字段访问权限
field.setAccessible(true);
// 设置私有字段的值
field.set(instance, 25);
// 通过反射获取字段的值
Object value = field.get(instance);
System.out.println(value);
运行的结果如下:
2.3、获取Class对象中的方法:
A:获取所有方法及信息,代码如下:
Class clazz = StudentDemo.class;
// 获取由public修饰的方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
运行的结果如下:
B、获取当前类中所有的方法,代码如下:
methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
System.out.println("方法访问修饰符:" + Modifier.toString(method.getModifiers()));
System.out.println("方法返回类型:" + method.getReturnType().getSimpleName());
System.out.println("方法名称:" + method.getName());
System.out.println("参数类型数组:" + Arrays.toString(method.getParameterTypes()));
System.out.println("参数个数:" + method.getParameterCount());
System.out.println("参数数组:" + Arrays.toString(method.getParameters()));
}
运行结果如下:
C:获取Class对象中的单个私有的方法并且赋值,代码如下:这个getUserName的访问修饰符是public的
// 创建一个Student对象
StudentDemo stu = new StudentDemo();
// 单独获取一个方法【方法名称必须和类中名完全匹配】,setAge方法是StudentDemo中私有的方法
Method method = clazz.getDeclaredMethod("setAge", int.class, String.class);
// 开启任何方法的访问权限
method.setAccessible(true);
Object object = method.invoke(stu, 10, "张三");
System.out.println(stu.getUsername());
运行的结果如下:
如果想要获取下私有的getAge方法,代码如下:
Method getMethod = clazz.getDeclaredMethod("getAge");
geMethod.setAccessible(true);
Object value1 = getMethod.invoke(stu);
System.out.println(value1);
运行的结果如下:
3、通过Class对象调用对应类的构造函数创建对象的实例
A、 获取使用public修饰的构造器,代码如下:
Class clazz = StudentDemo.class;
// 获取使用public修饰的构造器
Constructor[] constructors = clazz.getConstructors();
for (Constructor cl : constructors) {
System.out.println(cl);
}
运行的结果如下:
B:获取当前类中所有的构造器,代码如下:
constructors = clazz.getDeclaredConstructors();
for (Constructor cl : constructors) {
System.out.println(cl);
System.out.println("访问修饰符:"+Modifier.toString(cl.getModifiers()));
System.out.println("构造器名称:"+cl.getName());
System.out.println("参数类型数组:"+Arrays.toString(cl.getParameterTypes()));
}
运行的结果如下:
C、获取一个私有的构造器对象并且初始化这个对象,代码如下:
// 获取一个构造器对象
Constructor conl = clazz.getDeclaredConstructor(int.class, String.class);
// 开启任何构造函数的访问权限
conl.setAccessible(true);
// 通过参数个数和类型创建对象的实例
Object object = conl.newInstance(100, "AAA");
System.out.println(object);
运行的结果如下:
总结:上面的是反射中常用的方法。通过获取到类对象就可以为所欲为了。但是操作不了匿名内部类。