反射
获取字节码文件方式
/**
* 获取字节码文件的三种方式 第二个阶段
* 类对象阶段获取
*/
Class<?> forName = Class.forName("com.qr.junit.Reflex");
System.out.println(forName);
/**
* 类名.class 第一个阶段
* 源代码阶段获取
*/
Class class1 = Reflex.class;
System.out.println(class1);
/**
* 对象.getClass java代码的最后一个阶段
* 运行时阶段获取
*/
Reflex reflex = new Reflex();
Class<? extends Reflex> class2 = reflex.getClass();
System.out.println(class2);
//结论是三种运行状态获取的都是同一个字节码文件
对象
package com.qr;
public class Person {
private int id;
private String nameString;
public boolean isSend;
public int idCard;
protected double salary;
int aa;
public void save() {
System.out.println("保存不保存");
}
protected void dele() {
System.out.println("删除");
}
public Person() {
}
public Person(int id, String nameString, boolean isSend) {
this.id = id;
this.nameString = nameString;
this.isSend = isSend;
}
public Person(int id, String nameString, boolean isSend, int idCard) {
this.id = id;
this.nameString = nameString;
this.isSend = isSend;
this.idCard = idCard;
}
public Person(int id, String nameString, boolean isSend, double salary, int aa) {
this.id = id;
this.nameString = nameString;
this.isSend = isSend;
this.salary = salary;
this.aa = aa;
}
//私有构造
private Person(int id, String nameString, boolean isSend, int idCard, double salary, int aa) {
this.id = id;
this.nameString = nameString;
this.isSend = isSend;
this.idCard = idCard;
this.salary = salary;
this.aa = aa;
}
private void he(){
}
protected void hehe(){
}
void hehehe(){
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
public boolean isSend() {
return isSend;
}
public void setSend(boolean send) {
isSend = send;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public int getAa() {
return aa;
}
public void setAa(int aa) {
this.aa = aa;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +",idCard=" + idCard +
", nameString='" + nameString + '\'' +
", isSend=" + isSend +
", salary=" + salary +
", aa=" + aa +
'}';
}
}
获取属性
Person person = new Person();
Class<? extends Person> cls = person.getClass();
//获取所有 public 修饰的成员变量
// public boolean 修饰符 com.qr.Person.isSend所在的包和变量名称
Field[] fields = cls.getFields();
// System.out.println(fields);
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i]);
}
//获取指定名称的成员变量
Field idCard = cls.getField("idCard");
System.out.println(idCard);
//获取所有的成员变量
Field[] declaredFields = cls.getDeclaredFields();
System.out.println("获取所有的成员变量");
for (Object o :declaredFields) {
System.out.println(o);
}
System.out.println("获取指定的成员变量");
//如果nameString不存在,那么NoSuchFieldException
Field nameString = cls.getDeclaredField("nameString");
System.out.println(nameString);
/**
* 现上面的异常说明我们无法给私有属性赋值
* IllegalAccessException: Class com.qr.Reflex can not access a member of class com.qr.Person with modifiers "private"
* 需要使用暴力反射:
* setAccessible(true)
*/
nameString.setAccessible(true);
nameString.set(person,"张三");
Object o = idCard.get(person);
//这个默认值是0
System.out.println(o);
idCard.set(person,20);
System.out.println(person);
获取构造
Person person = new Person();
Class<? extends Person> p = person.getClass();
//获取构造方法,这个获取的只是五参数的构造
Constructor<? extends Person> constructor = p.getConstructor();
System.out.println(constructor);
System.out.println("获取所有的构造方法,除去私有构造外");
Constructor<?>[] constructors = p.getConstructors();
for (Object o :constructors) {
System.out.println(o);
}
Constructor<? extends Person> noParamConstruct = p.getConstructor();
System.out.println("空参数创建对象");
System.out.println(noParamConstruct);
// Constructor<? extends Person> constructor1 = p.getConstructor(String.class, int.class);,不存在此类构造会报错
/**
* 使用类的构造方法创建对象boolean是小写
*/
Constructor<? extends Person> construct = p.getConstructor(int.class, String.class,boolean.class);
System.out.println("构造方法创建对象"+construct);
//创建对象
Person per = construct.newInstance(20, "张三", true);
System.out.println("构造方法创建的对象");
System.out.println(per);
/**
* 使用私有构造创建对象是需要使用
* getDeclaredConstructor这个方法的
* 同时也需要暴力反射
*/
System.out.println("使用私有构造器创建对象");
Constructor<? extends Person> coss = p.getDeclaredConstructor(int.class, String.class, boolean.class, int.class, double.class, int.class);
System.out.println("私有构造创建对象也必须使用暴力反射");
coss.setAccessible(true);
Person perPrivate = coss.newInstance(2, "张三", false, 22, 18.8, 25);
System.out.println(perPrivate);
获取方法
Class<Person> personClass = Person.class;
/**
* 这个获取的是所有的方法包括set和get
* 获取不到private修饰到的方法
*/
Method[] method = personClass.getMethods();
for (Object o :method) {
System.out.println(o);
}
/**
* NoSuchMethodException:
* 这个方法只能获取pub修饰的方法
*/
// Method hehehe = personClass.getMethod("hehehe");
// Method hehe = personClass.getMethod("hehe");
// Method he = personClass.getMethod("he");
// System.out.println(hehehe);//void,没有修饰符修饰的方法
// System.out.println(hehe);//protected,没有修饰符修饰的方法
// System.out.println(he);//private,没有修饰符修饰的方法
Method save = personClass.getMethod("save");
System.out.println(save);
Person person = new Person();
//调用这个save方法,需要传入一个类对象,如果有参数也可以在后面设置参数
Object invoke = save.invoke(person);
// Object invoke = save.invoke(person, null);
System.out.println(invoke);
//获取类名
String name = personClass.getName();
System.out.println("获取类名");
System.out.println(name);
读取配置文件创建对象
className=com.qr.Person
methodName=save
Properties properties = new Properties();
InputStream resourceAsStream = Reflex.class.getClassLoader().getResourceAsStream("reflex.properties");
try {
properties.load(resourceAsStream);
String className = (String) properties.get("className");
String methodName = (String) properties.get("methodName");
Class<?> personClass = Class.forName(className);
Method method = personClass.getMethod(methodName);
Person person = new Person();
method.invoke(person);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
版权声明:本文为weixin_45540985原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。