**获取Class对象的三种方式** 1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
2. 类名.class:通过类名的属性class获取
* 多用于参数的传递
3. 对象.getClass():getClass()方法在Object类中定义着。
* 多用于对象的获取字节码的方式Class对象的作用
1. 获取多个成员变量
Field[] getFields() :获取所有public修饰的成员变量
Field getField(String name)获取指定名称的 public修饰的成员变量Field[] getDeclaredFields()获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name)
2. 获取构造方法
Constructor>[] getConstructors()
Constructor getConstructor(类>... parameterTypes)Constructor getDeclaredConstructor(类>... parameterTypes)
Constructor>[] getDeclaredConstructors()
3. 获取成员方法
Method[] getMethods()
Method getMethod(String name, 类>... parameterTypes)Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, 类>... parameterTypes) 4. 获取全类名
String getName() * Field:成员变量
* 操作:
1. 设置值
* void set(Object obj, Object value)
2. 获取值
* get(Object obj)
3. 忽略访问权限修饰符的安全检查
* setAccessible(true):暴力反射 * Constructor:构造方法
* 创建对象:
* T newInstance(Object... initargs)* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法 * Method:方法对象
* 执行方法:
* Object invoke(Object obj, Object... args)* 获取方法名称:
* String getName:获取方法名
【Java学习|Java>获取Class对象的三种方式,及其Method、Field、Constructor对象的使用方法】以下为实现代码
/*
用到的类
*/
public class Person {
public String str_name;
public Integer str_age;
private String ID_card_number;
public Person() {
}public Person(String str_name, Integer str_age, String ID_card_number) {
this.str_name = str_name;
this.str_age = str_age;
this.ID_card_number = ID_card_number;
}public String getStr_name() {
return str_name;
}public void setStr_name(String str_name) {
this.str_name = str_name;
}public Integer getStr_age() {
return str_age;
}public void setStr_age(Integer str_age) {
this.str_age = str_age;
}public String getID_card_number() {
return ID_card_number;
}public void setID_card_number(String ID_card_numver) {
this.ID_card_number = ID_card_numver;
}public void eat(int a){
System.out.println("Cat eat fish ~~~" + a);
}
public void eat1(int a){
System.out.println("My eat fish ~~~" + a);
}
}
* 获取public修饰的 属性字段的 值public class Reflex_Main01_PublicField {
public static void main(String[] args) throws Exception {
// 创建需要反射的类对象
Class personClass = Person.class;
// 获取字段属性对象
Field[] fields = personClass.getFields();
// 此方法可以返回private属性
// Field[] fields1 = personClass.getDeclaredFields();
// 打印字段属性对象的大小
System.out.println(fields.length);
// 获取一个Person对象
Person person = new Person();
for (Field f : fields) {
// 打印该字段
System.out.println(f);
String[] s1 = f.toString().split(" ");
String[] s2 = s1[s1.length - 1].split("\\.");
// 获取字段的名字
String field_name = s2[s2.length - 1];
// 获取字段名字属性的值
System.out.println("需要赋值的属性:" + field_name);
Field field = personClass.getField(field_name);
if (f.toString().contains("String")) field.set(person,"李四");
if (f.toString().contains("Integer")) field.set(person,89);
// 再次获取值
Object o1 = field.get(person);
System.out.println( o1 );
}
}
}
* 获取private修饰的属性的值public class Reflex_Main02_PrivateField {
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {// 创建class对象
Class personClass = Person.class;
// 获取字段对象
Field[] fields = personClass.getDeclaredFields();
// 创建Person对象 接下来会用到
Person person = new Person();
for (Field f : fields){
// 以空格为分隔符,将获取的字符串转换为字符串数组
String[] s1 = f.toString().split(" ");
// 以 . 为分隔符,将字符串分割为数组
String[] s2 = s1[s1.length - 1].split("\\.");
// 获取数组中最后一个元素
String field_name = s2[s2.length - 1];
// 打印获取到的名字
System.out.println(field_name);
// get field value 获取该字段的名字
Field field = personClass.getDeclaredField(field_name);
// 获取的字段中,含有私有属性字段,暴力反射该字段
field.setAccessible(true);
// set field value 设置属性的值,私有属性字段,暂时不知道如何设置
String field_name_c = f.toString();
// 判断获取到的字段是和类型,进行赋值
if(field_name_c.contains("String") && field_name_c.contains("str_name")) field.set(person , "张三");
if(field_name_c.contains("Integer") && field_name_c.contains("str_age")) field.set(person , 100);
Object o = field.get(person);
System.out.print(o + "\n");
}
}
}
* 获取Constructor构造方法import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class Reflex_Main03_Constructor {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {// 创建Person的反射class对象
Class personClass = Person.class;
// 创建constructor对象接受反射到的构造方法
Constructor constructorNoArguments = personClass.getConstructor();
Constructor constructor_Arguments = personClass.getConstructor(String.class, Integer.class, String.class);
// 打印接受到的值
System.out.println(constructorNoArguments);
// 使用构造方法对象创建Person对象
Person person = constructorNoArguments.newInstance();
person.str_name = "张三";
person.str_age = 19;
// 使用反射提供的方法,获取该类内的值
Field[] fields = personClass.getFields();
// 遍历数组内的值 ergodic value on the array
for (Field f : fields) {
Object o = f.get(person);
System.out.println(f.toString() + "\t Value -> " + o);
}// 创建构造方法的数组,接受构造方法
Constructor>[] constructors = personClass.getConstructors();
for (Constructor c : constructors) System.out.println(c);
}
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*
* 获取成员方法
* */public class Reflex_Main04_Method {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class personClass = Person.class;
Method[] methods = personClass.getMethods();
// 遍历获取到的成员方法
for (Method m : methods) System.out.println(m);
// 通过方法名字,获取方法
Method eat_method = personClass.getMethod("eat", int.class);
eat_method.invoke(new Person(),12);
}
}
推荐阅读
- java|学习Java期末总结
- 基础Java练习15(打印水仙花数)
- 基础Java练习19(测试从出生到现在活了多久)
- java|基础Java练习20(词频统计)
- 时区|springboot new Date() 时区差8小时
- 用Java十多年了,能“精通Java”了吗()
- JavaWeb|JSP-02动态网页技术基础
- java|Java-Mybatis(四): 动态SQL、标签、缓存
- Android开发|别人的H5页面为什么飞快(之 Webview 优化)