1. 什么是反射:
Java Reflaction in Action中的解释:反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就是反射可以在运行时根据指定的类名获得类的信息
个人理解:就是我们对于创建对象我们除了通过 new关键字创建外,还能通过什么创建呢?private的属属性真的不能获取吗?反射就能做到打破这些所谓的规则
反射和new创建对象谁的效率高? new
2. 反射在那些地方有用到
- jdbc加载驱动
- Spring ico
- 一些框架
3. 实际例子
- 通过反射创建对象
首先有一个Student对象
public class Student {
private String name;
private int age;
public Student() {
System.out.println("通过反射调用了无参构造函数");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1. 反射调用无参构造方法创建对象
public static void main(String[] args) throws Exception {
//1. 通过类路径(必须使用class的完整路径) 获取类的字节码文件
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
/*
2. 通过对象直接获取class对象
Student s = new Student();
Class<?> clazz = s.getClass();
3. 直接通过类获取
Class<?> clazz1 = Student .class;
*/
//使用无参构造函数创建对象
Object object = forName.newInstance();
Student student = (Student)object;
System.out.println(student);
}
运行结果:
2. 调用有参构造方法创建对象
//Student 构造方法
public Student(String name, int age) {
this.name = name;
this.age = age;
System.out.println("name:" + name + "age:" + age);
}
public static void main(String[] args) throws Exception {
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
Constructor<?> constructor = forName.getConstructor(String.class, int.class);
Object object = constructor.newInstance("小奏", 18);
}
运行结果:
3. 调用私有构造方法
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
Constructor constructor1 = forName.getDeclaredConstructor();
constructor1.setAccessible(true);
Student student = (Student) constructor1.newInstance();
System.out.println(student);
4. 获取所有方法和方法返回值
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
//获取类所有方法,包括继承方法
Method[] methods = forName.getMethods();
//获取类的所有方法,不包括继承
Method[] methods1 = forName.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法:" + method.getName() + "返回值: " + method.getReturnType());
}
System.out.println();
for (Method method : methods1) {
System.out.println("方法:" + method.getName() + "返回值: " + method.getReturnType());
}
运行结果:
5. 获取所有成员属性名
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
Field[] fields = forName.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
}
6. 访问私有成员变量
Class<?> forName = Class.forName("com.springboot.dubbo.model.entity.Student");
Object object = forName.newInstance();
Field field = forName.getDeclaredField("name");
//设置运行访问私有属性
field.setAccessible(true);
field.set(object,"阿离");
Student student = (Student) object;
System.out.println(student.getName());
7. 执行方法
Class<?> clazz = Class.forName("com.springboot.dubbo.model.entity.Student");
Student s= (Student) clazz.newInstance();
Method method = clazz.getMethod("getTest");
Method method1 = clazz.getMethod("getTest", String.class);
method.invoke(s);
method1.invoke(s, "ha");
Student的方法
public String getTest() {
System.out.println("调用了测试方法");
}
public String getTest(String s ) {
System.out.println("传入参数" + s);
}