目录
一、获取类对象
public class ReflectDemo {
public static void main(String[] args) throws Exception {
//方式一,最方便
//使用类的class属性来获取类对应的Class对象
Class<Student> c1 = Student.class;
System.out.println(c1);
Class<Student> c2 = Student.class;
System.out.println(c1 == c2);
System.out.println("=============");
//方式二
//调用对象的getClass()方法,返回该对象所属类的Class对象
Student s=new Student();
Class<? extends Student> c3=s.getClass();
System.out.println(c1==c3);
System.out.println("=============");
//方式三,灵活性最高
//使用Class类中的静态方法forName(String className)
Class<?> c4=Class.forName("test01.Student");
System.out.println(c1==c4);
}
}
从运行结果可以看出获取的类对象都是相同的!
二、通过反射操作构造方法
package com.dragonwu;
public class Student {
private String name;
private Integer age;
public Boolean isMale;
public Student() {
}
public Student(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
private Student(String name) {
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
获取对象构造方法:
package com.dragonwu;
import java.lang.reflect.Constructor;
public class TestDemo01 {
public static void main(String[] args) throws Exception {
//获取Class对象
Class<?> c = Class.forName("com.dragonwu.Student");
//只能拿到公共的构造方法
Constructor<?>[] cons = c.getConstructors();
for (Constructor<?> con : cons) {
System.out.println(con);
}
System.out.println("=====================");
//可以拿到所有构造方法包括私有的
Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("=====================");
Constructor<?> con = c.getConstructor();
//通过反射创建对象实例
Object obj = con.newInstance();
System.out.println(obj);
}
}
运行结果:
案例二:
package com.dragonwu;
import java.lang.reflect.Constructor;
public class TestDemo02 {
public static void main(String[] args) throws Exception{
//获取Class对象
Class<?> c = Class.forName("com.dragonwu.Student");
Constructor<?> con = c.getConstructor(String.class, Integer.class);
Object obj = con.newInstance("Jack", 12);
System.out.println(obj);
System.out.println("==============================");
//私有方法使用
Constructor<?> con2 = c.getDeclaredConstructor(String.class);
//暴力反射,值为true取消访问检查,这样private的方法也可被调用
con2.setAccessible(true);
Object obj2 = con2.newInstance("Mark");
System.out.println(obj2);
}
}
效果:
三、反射操作成员变量
package com.dragonwu;
import java.lang.reflect.Field;
public class TestDemo03 {
public static void main(String[] args) throws Exception {
//获取Class对象
Class<?> aClass = Class.forName("com.dragonwu.Student");
//获取共有所有属性变量
Field[] fields = aClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("===================");
//获取所有属性变量
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
}
运行结果:
获取单个的成员变量:
package com.dragonwu;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class TestDemo03 {
public static void main(String[] args) throws Exception {
//获取Class对象
Class<?> aClass = Class.forName("com.dragonwu.Student");
//public
Field isMale = aClass.getField("isMale");
//private
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);//将忽略private检测
//获取无参构造方法,再实例化对象
Constructor<?> constructor = aClass.getConstructor();
Object obj = constructor.newInstance();
//给实例赋值
name.set(obj, "Jack");//给实例的name变量赋值
isMale.set(obj, true);
System.out.println(obj);
}
}
运行结果:
四、反射操作成员方法
在二中的student对象中添加两个方法以便操作:
private void sayHello(){
System.out.println("hello student");
}
public void study(){
System.out.println("I'm studying!");
}
案例一
package com.dragonwu;
import java.lang.reflect.Method;
public class TestDemo04 {
public static void main(String[] args) throws Exception{
//创建Class对象
Class<?> c = Class.forName("com.dragonwu.Student");
//获取所有公共方法
Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("=====================");
//获取所有方法
Method[] declaredMethods = c.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
}
运行结果:
案例二:调用方法
package com.dragonwu;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestDemo04 {
public static void main(String[] args) throws Exception{
//创建Class对象
Class<?> c = Class.forName("com.dragonwu.Student");
//获取对应的方法
Method m = c.getDeclaredMethod("sayHello");
//忽略private检测
m.setAccessible(true);
//创建实例对象
Constructor<?> constructor = c.getConstructor();
Object obj = constructor.newInstance();
//调用方法
m.invoke(obj);
}
}
运行结果:
五、反射读取配置文件实例对象
后端框架中大多用到了此种思路。