反射:
目的:可以帮助开发者更快更方便的封装框架实现扩展功能;
反射是动态的获取java的元数据信息,也就是编译后的class文件。
反射的用途:
1.通过反射机制访问java对象的属性,方法,构造方法等
2.JDBC加载驱动连接 class.forname
Class.forName(“com.mysql.jdbc.Driver”); // 动态加载mysql驱动
3.Spring容器框架IOC实例化对象
4.自定义注解生效(反射+Aop)
5.第三方核心的框架 mybatis orm
反射的优缺点:
1、优点:可以帮助开发者更快更方便的封装框架实现扩展功能。
2、缺点:
(1)反射会消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
反射的使用
1、利用反射创建对象的方式
package com.dbgs.blct.test;
import com.dbgs.blct.test.entity.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/** 获取class的三种方法 */
public class Test {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//创建方法1
Class<User> user1 = User.class;
//创建方法2
Class<?> user2 = Class.forName("com.dbgs.blct.test.entity.User");
System.out.println(user1==user2);
//创建方法3,直接new
User user4 = new User();
Class userClass4 = user4.getClass();
}
}
实体
package com.dbgs.blct.test.entity;
public class User {
private String name;
private int age;
public String pubUser;
public User() {
System.out.println("无参构造函数");
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
public String getPubUser() {
return pubUser;
}
public void setPubUser(String pubUser) {
this.pubUser = pubUser;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", pubUser='" + pubUser + '\'' +
'}';
}
}
2、反射常用的API
import com.dbgs.blct.test.entity.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//创建对象
Class<?> user2 = Class.forName("com.dbgs.blct.test.entity.User");
//获取用public修饰的字段
Field[] fields = user2.getFields();
for (Field field : fields) {
System.out.println(field);
}
//获取所有的字段
Field[] fieldsAll = user2.getDeclaredFields();
for (Field field : fieldsAll) {
System.out.println(field);
}
//默认构造无参构造函数
User user = (User) user2.newInstance();
//构建有参的构造方法,根据属性传入参数
Constructor<User> constructor = (Constructor<User>) user2.getConstructor(String.class, int.class);
User user3 = constructor.newInstance("name", 1);
System.out.println(user3);
//反射调用公共方法,括号里是公共方法名称
Method yws = user2.getDeclaredMethod("yws");
yws.invoke(user);
//反射调用私有方法,括号里是私有方法名称
Method ywsprivate = user2.getDeclaredMethod("ywsprivate");
//赋予访问权限
ywsprivate.setAccessible(true);
ywsprivate.invoke(user);
//反射调用有参数有返回值的方法,括号里是方法名称,和参数类型元数据
Method ywssum = user2.getDeclaredMethod("ywssum", int.class, int.class);
ywssum.setAccessible(true);
//传入参数
Object invoke = ywssum.invoke(user,1, 4);
System.out.println("反射调用有参数有返回值的方法"+invoke);
}
}
实体添加方法
public void yws() {
System.out.println("公共方法");
}
public void ywsprivate() {
System.out.println("私有方法");
}
public int ywssum(int i,int j) {
System.out.println("有参数有返回值");
return i+j;
}