JAVA中的反射 2020-03-14 16:10 # 简单小例子 `User` ```java package Reflex.one; import lombok.Data; import java.sql.Date; /** * model对象 */ @Data public class User { private Long id; private String userName; private String passWord; private Date dateTime; } ``` `Demo` ```java package Reflex.one; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 简单的反射使用 * * new User() “正射” 程序在未运行的时候已经确定了要执行的类:User * * 反射:程序执行期间才知道操作的类是什么,并能在运行期间获得类的完整构造(结构),并可调用方法 */ public class Demo { public static void main(String[] args) { try { //获得类 Class<?> c = Class.forName("Reflex.one.User"); //获得类的构造 Constructor<?> constructor = c.getConstructor(); //通过构造实例化对象 Object instance = constructor.newInstance(); //获得set方法 Method setUserName = c.getMethod("setUserName", String.class); //执行set方法。参数:要执行的实例,执行方法所需的参数 setUserName.invoke(instance,"qwe"); //获得get方法 Method getUserName = c.getMethod("getUserName"); //执行get方法。参数:要执行的实例 Object invoke = getUserName.invoke(instance); //输出执行结果 System.out.println(invoke); } catch (ClassNotFoundException e) { e.printStackTrace(); System.out.println("类不存在"); }catch (NoSuchMethodException e) { e.printStackTrace(); System.out.println("类中没有这样的方法"); }catch (InstantiationException e) { e.printStackTrace(); System.out.println("实例化失败"); } catch (IllegalAccessException e) { e.printStackTrace(); System.out.println("实例化失败"); } catch (InvocationTargetException e) { e.printStackTrace(); System.out.println("实例化失败"); } } } ``` # 反射常用API: 从上面简单的例子我们可以看出使用反射操作类,分为以下几个主要步骤: - 获得类Class - 得到实例化对象 - 得到类的方法 - 通过方法操作对象 ### model对象 `User` ```java package Reflex.one; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.sql.Date; /** * model对象 */ @Data @AllArgsConstructor @NoArgsConstructor public class User { private Long id; private String userName; private String passWord; private Date dateTime; public String updateTime; public String depId; String level; public User(Long id, String userName, String passWord) { this.id = id; this.userName = userName; this.passWord = passWord; } } ``` ## 获取Class对象 > 得到Class对象的几种方法: > > 1、通过类路径 > > 2、通过传入的类 > > 3、通过类已经实例化的对象 ```java //得到Class对象的3种方法 public static void main1(String[] args)throws ClassNotFoundException { //1、通过类路径 Class<?> aClass = Class.forName("Reflex.one.User"); //2、通过传入的类 Class<User> aClass1 = User.class; //3、通过类已经实例化的对象 User user = new User(); Class<? extends User> aClass2 = user.getClass(); } ``` ## 获取实例化对象 > 得到Class类实例对象的几种方法: > > 1、通过Class直接newInstance > > 2、通过Class得到构造函数,再通过具体构造函数newInstance ```java //通过Class获得类实例对象的2种方式 public static void main2(String[] args) throws Exception { Class<User> c = User.class; //1、通过Class直接newInstance。默认使用无参的构造函数实例化对象 Object instance = c.newInstance(); //2、通过Class先得到类的构造函数,再通过构造函数newInstance。好处:可以选择通过哪个构造函数来实例化对象 Constructor<User> constructor = c.getConstructor(); User user = constructor.newInstance(); //有参的构造函数 Constructor<User> constructor1 = c.getConstructor(Long.class, String.class, String.class); User user2 = constructor1.newInstance(111L, "qqq", "eee"); System.out.println(user2); } ``` ## 获取类属性 > 得到类属性的几种方法: > > 1、通过Class的getFields(),只能得到公有属性 > > 2、通过Class的getDeclaredFields(),可得到所有属性 ```java //通过Class获取类的属性 public static void main3(String[] args) { Class<User> userClass = User.class; //getFields()。无法获取私有属性和默认(default修饰)属性 /*Field[] fields = userClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); }*/ //getDeclaredFields()。获取包括私有,默认属性在内的 全部属性 Field[] declaredFields = userClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField.getName()); } /* 如果想要获取类的私有属性、方法、构造器,就要用到declared关键字 */ } ``` **若想得到所有的属性、方法、构造函数,则必须使用带有declared关键字的方法。** --- 在我的项目HPoiUtil中使用到了反射机制,详情:https://github.com/hanhanhanxu/HPoiUtil --- 如果你想更清楚的了解,请参考并发编程网的反射系列:http://ifeve.com/java-reflection-tutorial/ --END--
发表评论