持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,[点击查看活动详情]
什么是反射
Java 反射机制是 Java 语言一个很重要的特性,它使得 Java 具有了“动态性”。在 Java
程序运行时,对于任意的一个类,我们能不能知道这个类有哪些属性和方法呢?对于任意的
一个对象,我们又能不能调用它任意的方法?答案是肯定的!这种动态获取类的信息以及动
态调用对象方法的功能就来自于 Java 语言的反射(Reflection)机制。
反射的作用
简单来说两个作用,RTTI(运行时类型识别)和 DC(动态创建)。
我们知道反射机制允许程序在运行时取得任何一个已知名称的 class 的内部信息,包括其 modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变 fields 内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!
创建对象的过程
获取class对象的方法
getclass
Users users=new Users();
Class clazz=users.getClass();
Class clazz2=users.getClass();
System.out.println(clazz);
System.out.println(clazz.getName());
System.out.println(clazz2==clazz);
通过.class静态属性获取class对象
Class clazz=Users.class;
System.out.println(clazz);
System.out.println(clazz.getName());
通过forName方法过去class对象
Class clazz=Class.forName("com.test.Users");
System.out.println(clazz);
获取类的构造方法
Class clazz=Users.class;
Constructor[] arr=clazz.getDeclaredConstructors();
for (Constructor c:arr)
{
System.out.println(c);
}
System.out.println("-------------------------");
Constructor[] arr1=clazz.getConstructors();
for (Constructor c:arr1)
{
System.out.println(c);
}
System.out.println("-------------------------");
Constructor c=clazz.getDeclaredConstructor(int.class);
System.out.println(c);
System.out.println("-------------------------");
Constructor d=clazz.getConstructor(null);
System.out.println(d);
| 方法名 | 描述 |
|---|---|
| getDeclaredConstructors() | 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表 示的类声明的所有构造方法。 |
| getConstructors() | 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共(public)构造方法。 |
| getConstructor(Class<?>... parameterTypes) | 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指 定公共(public)构造方法。 |
| getDeclaredConstructor(Class<?>... parameterTypes) | 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类 或接口的指定构造方法。 |
通过构造方法创建对象
Class clazz=Users.class;
Constructor constructor=clazz.getConstructor(String.class,int.class);
Object o= constructor.newInstance("kaeiy",18);
Users users=(Users) o;
System.out.println(users.getUsername()+"\t"+users.getUserage());
使用newInstance对方法反射做实例对象
获取类的成员变量
| 方法名 | 描述 |
|---|---|
| getFields() | 返回 Field 类型的一个数组,其中包含 Field 对象的所有公共(public)字段。 |
| getDeclaredFields() | 返回 Field 类型的一个数组,其中包含 Field 对象的所有字段。 |
| getField(String fieldName) | 返回一个公共成员的 Field 指定对象。 |
| getDeclaredField(String fieldName) | 返回一个 Field 指定对象。 |
Class clazz=Users.class;
Field[] fields=clazz.getFields();
for(Field f:fields)
{
System.out.println(f);
}
System.out.println("--------------------");
Field[] fields2=clazz.getDeclaredFields();
for(Field f:fields2)
{
System.out.println(f);
}
System.out.println("--------------------");
Field field=clazz.getField("userage");
System.out.println(field);
System.out.println("--------------------");
Field field1=clazz.getDeclaredField("username");
System.out.println(field1);
操作成员变量
Class clazz=Users.class;
Field field=clazz.getField("userage");
Object o=clazz.newInstance();
field.set(o,18);
System.out.println(field.get(o));
Class类也有newInstance函数,调用的是无参构造
获取类的方法
| 方法名 | 描述 |
|---|---|
| getMethods() | 返回一个 Method 类型的数组,其中包含 所有公共(public)方法。 |
| getDeclaredMethods() | 返回一个 Method 类型的数组,其中包含 所有方法。 |
| getMethod(String name, Class<?>... parameterTypes) | 返回一个公共的 Method 方法对象。 |
| getDeclaredMethod(String name, Class<?>... parameterTypes) | 返回一个方法 Method 对象 |
获取方法
Class clazz = Users.class;
Method[] methods = clazz.getMethods();
for(Method m: methods){
System.out.println(m);
System.out.println(m.getName());
}S
ystem.out.println("---------------------------");
Method[] methods2 = clazz.getDeclaredMethods();
for(Method m: methods2){
System.out.println(m);
System.out.println(m.getName());
}S
ystem.out.println("--------------------------");
Method method = clazz.getMethod("setUserage", int.class);
System.out.println(method.getName());
System.out.println("--------------------------");
Method method1 = clazz.getDeclaredMethod("suibian");
System.out.println(method1.getName());
调用方法
Class clazz = Users.class;
Method method = clazz.getMethod("setUsername",String.class);
//实例化对象
Object obj = clazz.newInstance();
//通过 setUserName 赋值
method.invoke(obj,"oldlu");
//通过 getUserName 获取值
Method method1 = clazz.getMethod("getUsername");
Object value = method1.invoke(obj);
System.out.println(value);
\