一:Other
获取运行时类的父类
public void test1() {
Class<Person> clazz = Person.class;
Class<? super Person> superClass = clazz.getSuperclass();
System.out.println(superClass);
}
通过反射获取并运行配置文件
public void test2() throws Exception {
// 获取配置文件的对象
Properties properties = new Properties();
// 获取输入流(读取配置文件 将配置文件以流的形式读取)
FileReader in = new FileReader(new File("properties"));
// 将流加载到配置文件对象中
properties.load(in);
// 释放资源
in.close();
// 获取用户名和密码
String uesrName = properties.getProperty("user");
String password = properties.getProperty("password");
System.out.println("用户名:"+uesrName+" 密码"+password);
// 通过反射获取Class对象
Class<?> clazz = Class.forName(properties.getProperty("className"));
// 获取show()方法
Method method = clazz.getMethod(properties.getProperty("methodName"));
// 调用show方法
// method.invoke(clazz.getConstructor().newInstance());
Student student = (Student) clazz.newInstance();
method.invoke(student);
}
泛型删除:程序编译后产生的字节码文件(.class)是没有泛型约束的,这种现象称为泛型的擦除。
public void test3() throws Exception {
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(123);
// 获取ArrayList字节码对象
Class<? extends ArrayList> c = arr.getClass();
// 通过反射的方式获得add()方法
Method m = c.getMethod("add", Object.class);
// 调用方法
m.invoke(arr, "abc");
System.out.println(arr);
}
二.Method
获取运行时类中指定的方法
public void test1() {
Class clazz = Person.class;
// 1.getMethods():获取运行时类及其父类中声明为Public的方法
Method[] m1 = clazz.getMethods();
for (Method m : m1) {
System.out.println(m);
}
System.out.println("------------------------");
// 2.getDeclaredMethods():获取运行时类本身声明的所有方法
Method[] m2 = clazz.getDeclaredMethods();
for (Method method : m2) {
System.out.println(method);
}
}
调用运行时类中指定的方法
public void test2() throws Exception {
// 创建运行时类的对象
Class<Person> clazz = Person.class;
Person p = (Person) clazz.newInstance();
// 获取属性
Field f_name = clazz.getDeclaredField("name");
Field f_age = clazz.getDeclaredField("age");
// 允许访问
f_name.setAccessible(true);
f_age.setAccessible(true);
// 设置属性值
f_name.set(p, "tina");
f_age.set(p, 30);
// 1.获取运行时类声明为public的方法
Method m1 = clazz.getMethod("show");
// 调用方法 invoke(指定对象,方法参数)
m1.invoke(p);
// 2.调用有返回值的方法
Method m2 = clazz.getMethod("sayHello");
// 调用方法并接受返回值
Object returnVal1 = m2.invoke(p);
System.out.println(returnVal1);
// 3.调用静态方法
Method m3 = clazz.getMethod("info");
// 相当于 类名.方法名
m3.invoke(Person.class);
// 4.调用带参数的方法
// 获取运行时类中所有的方法 getDeclaredMethod()
Method m4 = clazz.getDeclaredMethod("display", String.class);
m4.invoke(p, "china");
}
调用有参数的构造器 创建运行时类的对象 调用相关的方法
public void test3() throws Exception {
Class<Person> clazz = Person.class;
// 得到有参数的构造器
Constructor<Person> cons = clazz.getConstructor(String.class,int.class);
// 通过有参的构造器创建运行时类的实例(初始化成员属性)
Person p = cons.newInstance("tom",25);
System.out.println(p);
// 获取方法
Method method = clazz.getMethod("display",String.class);
// 调用方法
method.invoke(p, "USA");
}
三:Field
1.getFields():获取运行时类及其父类中声明的为public类型的属性
2.getDeclareFields():获取运行时类本身声明的所有属性
public void test1() {
Class clazz = Person.class;
// 1.getFields():获取运行时类及其父类中声明的为public类型的属性
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
// 2.getDeclareFields():获取运行时类本身声明的所有属性
Field[] fields2 = clazz.getDeclaredFields();
for (Field field : fields2) {
// 获取属性名称
System.out.println(field.getName());
}
}
获取属性的各个部分内容(权限修饰符、类型、名称)
public void test2() {
Class clazz = Person.class;
Field[] fields = clazz.getDeclaredFields();
for (Field f : fields) {
// 1.获取每个属性的访问修饰符
int modifiers = f.getModifiers();
// Modeifier.toString(int num):将num对应的数值转换为对应的访问修饰符 1 - public 2 - private
System.out.println(Modifier.toString(modifiers));
// 获取属性的类型
Class<?> type = f.getType();
String typeName = type.getName();
System.out.println(typeName);
// 3.获取属性名称
System.out.println(f.getName());
}
}
获取运行时类指定的属性
public void test3() throws Exception {
Class clazz = Class.forName("com.hpe.reflect.Person");
// 1.获取指定的属性
// getField(String name):获取运行时类中声明为public指定属性名的属性
Field name = clazz.getField("name");
// 2.创建运行时类的对象
Person p = (Person) clazz.newInstance();
System.out.println(p);
// 3.设置属性值
name.set(p, "ecic");
System.out.println(p);
// 4.getDeclareField(Sting filedName):获取运行时类指定的属性名
Field age = clazz.getDeclaredField("age");
// 由于属性权限修饰符的限制,为了保证给属性赋值,需要在操作前使得该属性可被操作
age.setAccessible(true);
age.set(p, 15);
System.out.println(p);
}
四:构造器
方法与上方类似