概念
反射:将类的各个组成部分封装为其他对象,这就是反射机制。
好处:
- 可以在程序运行过程中,操作这些对象。
- 可以解耦,提高程序的可扩展性。

获取Class对象的方式
Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
多用于配置文件,将类名定义在配置文件中。读取文件,加载类
类名.class:通过类名的属性class获取
多用于参数的传递
对象.getClass():getClass()方法在Object类中定义着。
多用于对象的获取字节码的方式
结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
示例1:
package com.alpaak.part12;import com.alpaak.part12.demo5.MyAnno;public class Person {private String name;private int age;private static String city="广州";public String a;protected String b;String c;private String d;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public void eat(){System.out.println("吃饭。。。。");}public void eat(String name){System.out.println(name + ",吃饭。。。。");}public void sleep(){System.out.println("睡觉。。。。");}@MyAnnopublic void test () {System.out.println("注解测试下");}}
package com.alpaak.part12.demo1;import com.alpaak.part12.Person;/*** 获取Class对象的方式*/public class ReflectDemo1 {public static void main(String[] args) {/*1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象- 多用于配置文件,将类名定义在配置文件中。读取文件,加载类2. 类名.class:通过类名的属性class获取- 多用于参数的传递3. 对象.getClass():getClass()方法在Object类中定义着。- 多用于对象的获取字节码的方式*///1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象try {Class<?> aClass = Class.forName("com.alpaak.part12.Person");//类名.class:通过类名的属性class获取Class<Person> personClass = Person.class;//3. 对象.getClass():getClass()方法在Object类中定义着。Person person = new Person();Class<? extends Person> aClass2 = person.getClass();System.out.println("aClass==personClass:"+(aClass==personClass));System.out.println("aClass2==personClass:"+(aClass==personClass));} catch (ClassNotFoundException e) {e.printStackTrace();}}}
Class对象功能
获取成员变量
- Field[] getFields() :获取所有public修饰的成员变量
- Field getField(String name) 获取指定名称的 public修饰的成员变量
- Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
- Field getDeclaredField(String name)
Field:成员变量
- 设置值 void set(Object obj, Object value)
- 获取值 get(Object obj)
- 忽略访问权限修饰符的安全检查(暴力反射) setAccessible(true)
示例2:
```java package com.alpaak.part12.demo2;
import com.alpaak.part12.Person;
import java.lang.reflect.Field;
/**
获取成员变量 */ public class ReflectDemo2 {
public static void main(String[] args) throws Exception{
/* - Field[] getFields() :获取所有public修饰的成员变量 - Field getField(String name) 获取指定名称的 public修饰的成员变量 - Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符 - Field getDeclaredField(String name) */ Class<Person> personClass = Person.class; // Field[] fields = personClass.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("-----------"); Field[] declaredFields = personClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField); } /* 1. 设置值 - void set(Object obj, Object value) 2. 获取值 - get(Object obj) 3. 忽略访问权限修饰符的安全检查 - setAccessible(true):暴力反射 */ System.out.println("------------------"); Field a = personClass.getField("a"); Person p = new Person(); a.set(p,"zhongguo"); //获取值 Object o = a.get(p); System.out.println("o:"+o); //a.setAccessible(true); Field name = personClass.getDeclaredField("name"); /* 报错 Class com.alpaak.part12.demo2.ReflectDemo2 can not access a member of class com.alpaak.part12.Person with modifiers "private" */ System.out.println("name:"+name.get(p));} }
<a name="qGa22"></a>
## 获取构造方法
- Constructor<?>[] getConstructors()
- Constructor<T> getConstructor(Class<?>... parameterTypes)
- Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
- Constructor<?>[] getDeclaredConstructors()
<a name="oxpnr"></a>
### Constructor:构造方法
创建对象:T newInstance(Object... initargs) <br />如果使用空参数构造方法创建对象,操作可以简化:**Class对象的newInstance方法**
<a name="ZlSVq"></a>
### 示例3:
```java
package com.alpaak.part12.demo3;
import com.alpaak.part12.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* 获取构造方法
*/
public class ReflectDemo3 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
/*
2. 获取构造方法们
- Constructor<?>[] getConstructors()
- Constructor<T> getConstructor(类<?>... parameterTypes)
- Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
- Constructor<?>[] getDeclaredConstructors()
*/
Class<Person> personClass = Person.class;
//获取有参的构造方法
Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
//创建对象1
Person person1 = constructor.newInstance("张三", 23);
System.out.println(person1);
//获取无参的构造方法
Constructor<Person> constructor2 = personClass.getConstructor();
System.out.println("constructor2:"+constructor2);
//创建对象2
Person person2 = constructor2.newInstance();
System.out.println("person2:"+person2);
//创建对象3
Person person3 = personClass.newInstance();
System.out.println("person3:"+person3);
System.out.println("------------");
Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
System.out.println("-------------");
//构造器暴力访问
//constructor2.setAccessible(true);
}
}
获取成员方法
- Method[] getMethods() :获取类里面所有的public方法,包括父类里面的public方法
- Method getMethod(String name, 类<?>… parameterTypes)
- Method[] getDeclaredMethods() :获取类里面声明的所有的方法,不包括父类的方法
- Method getDeclaredMethod(String name, 类<?>… parameterTypes)
Method:方法对象
执行方法:Object invoke(Object obj, Object… args)
获取方法名称:String getName示例4:
```java package com.alpaak.part12.demo4;
import com.alpaak.part12.Person;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
/**
获得成员方法 */ public class ReflectDemo4 { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
/* 3. 获取成员方法们: - Method[] getMethods() - Method getMethod(String name, 类<?>... parameterTypes) - Method[] getDeclaredMethods() - Method getDeclaredMethod(String name, 类<?>... parameterTypes) */ Class<Person> personClass = Person.class; //获取指定名称的方法 Method eat = personClass.getMethod("eat"); // Person p = new Person(); //执行方法 eat.invoke(p); //获取指定名称,并且带参数的方法 Method eat2 = personClass.getMethod("eat", String.class); //执行带参数的方法 eat2.invoke(p,"wowo"); System.out.println("--------------"); //获取所有public修饰的方法 Method[] methods = personClass.getMethods(); for (Method method : methods) { System.out.println(method); //方法名 System.out.println(method.getName()); } System.out.println("-----------------"); //获取类名 String name = personClass.getName(); System.out.println("类名:"+name);在程序使用(解析)注解
在程序使用(解析)注解:获取注解中定义的属性值
- 获取注解定义的位置的对象 (Class,Method,Field)
- 判断注解是否存在
- isAnnotationPresent(Class)
- 获取指定的注解
- getAnnotation(Class)
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
/**
- 定义注解
*/
@Target({ElementType.METHOD})
//@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
int age() default 0;
}
java package com.alpaak.part12.demo5;
import com.alpaak.part12.Person;
import java.lang.reflect.Method;
/**
在程序使用(解析)注解 */ public class Demo5 { public static void main(String[] args) throws NoSuchMethodException {
/* - 在程序使用(解析)注解:获取注解中定义的属性值 1. 获取注解定义的位置的对象 (Class,Method,Field) - isAnnotationPresent(Class) 1. 获取指定的注解 - getAnnotation(Class) 3. 调用注解中的抽象方法获取配置的属性值 */ Class<Person> personClass = Person.class; //// System.out.println(personClass.isAnnotationPresent(MyAnno4.class)); // //获取类上面的注解,获取注解定义的位置的对象 // MyAnno4 annotation = personClass.getAnnotation(MyAnno4.class); // // //获取注解中定义的属性值 // int age = annotation.age(); // System.out.println(“age:”+age);
System.out.println("------------"); Method test = personClass.getMethod("test"); System.out.println(test.isAnnotationPresent(MyAnno.class)); //获取方法上定义的注解 if (test.isAnnotationPresent(MyAnno.class)) { System.out.println("test方法有定义注解"); MyAnno annotation2 = test.getAnnotation(MyAnno.class); int age2 = annotation2.age(); System.out.println("age2:" + age2); }
}
}
```
