事例:
自定义注解:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Documented
@Inherited //可以继承
public @interface TestAnno {
String value() default "";
}
测试类
@TestAnno
public class Test {
@TestAnno("年龄")
private int age;
private String name;
public Test(int age, String name) {
this.age = age;
this.name = name;
}
public Test() {
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Test{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
@TestAnno
private void doPrivate(String str){
System.out.println("私有方法调用" +str);
}
}
2. 反射应用
1.注解
//反射-属性示例
public class AnnotationDemo {
private Object getTest(){
try {
Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");
Constructor constructor ;
Class[] classes = {int.class, String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
try {
Object aaa = constructor.newInstance(1, "aaa");
return aaa;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
//遍历所有方法、属性,获取注解响应的内容
@org.junit.Test
public void field1() throws NoSuchFieldException, IllegalAccessException {
Class<Test> testClass = Test.class;
TestAnno declaredAnnotation = testClass.getDeclaredAnnotation(TestAnno.class);
if(declaredAnnotation != null){
System.out.println("类上包含了TestAnno注解");
}
Method[] declaredMethods = testClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if(declaredMethod.getAnnotation(TestAnno.class) != null){
System.out.println(declaredMethod.getName() + "方法包含TestAnno注解");
}
}
Field[] declaredFields = testClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
TestAnno declaredAnnotation1 = declaredField.getDeclaredAnnotation(TestAnno.class);
if(declaredAnnotation1 != null){
System.out.println(declaredField.getName() + "属性包含TestAnno注解");
System.out.println("注解的value为"+declaredAnnotation1.value());
}
}
}
}
2.构造器
//反射-构造方法示例
public class ConstructDemo {
//获取所有构造方法
@org.junit.Test
public void constuct(){
Class c4 = Test.class;
Constructor[] constructors ;
constructors = c4.getDeclaredConstructors();
for (Constructor constructor : constructors) {
// Modifier 类提供了 static方法和常量,对类和成员访问修饰符进行解码。
System.out.print(Modifier.toString(constructor.getModifiers()) + "参数:");
Class[] parametertypes = constructor.getParameterTypes();
//打印所有的参数
for(Class clazz : parametertypes){
System.out.print(clazz.getName() + " ");
}
System.out.println("");
}
}
//获取指定的构造方法
@org.junit.Test
public void constuct2(){
Class c4 = Test.class;
Constructor constructor ;
Class[] classes = {int.class,java.lang.String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
// Modifier 类提供了 static方法和常量,对类和成员访问修饰符进行解码。
System.out.print(Modifier.toString(constructor.getModifiers()) + "参数:");
Class[] parametertypes = constructor.getParameterTypes();
//打印所有的参数
for(Class clazz : parametertypes){
System.out.print(clazz.getName() + " ");
}
System.out.println("");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
//调用构造方法
@org.junit.Test
public void constuct3(){
Class c4 = Test.class;
Constructor constructor ;
Class[] classes = {int.class,java.lang.String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
try {
Object aaa = constructor.newInstance(1, "aaa");
System.out.println(aaa);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
//案例:模拟一下spring创建bean
@org.junit.Test
public void constuct4(){
try {
Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");
Constructor constructor ;
Class[] classes = {int.class,java.lang.String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
try {
Object aaa = constructor.newInstance(1, "aaa");
System.out.println(aaa);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3.属性
//反射-属性示例
public class FieldDemo {
private Object getTest(){
try {
Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");
Constructor constructor ;
Class[] classes = {int.class, String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
try {
Object aaa = constructor.newInstance(1, "aaa");
return aaa;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
//设置和获取属性
@org.junit.Test
public void field1() throws NoSuchFieldException, IllegalAccessException {
Class<Test> testClass = Test.class;
Field field = testClass.getDeclaredField("name");
Object test = getTest();
field.setAccessible(true);
field.set(test,"张三");
System.out.println(field.get(test));
}
//案例:map和实体类之间的转换
/**
* Map转成实体对象
* @param map map实体对象包含属性
* @param clazz 实体对象类型
* @return
*/
public static Object map2Object(Map<String, Object> map, Class<?> clazz) {
if (map == null) {
return null;
}
Object obj = null;
try {
obj = clazz.newInstance();
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
int mod = field.getModifiers();
if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
continue;
}
field.setAccessible(true);
field.set(obj, map.get((field.getName())));
}
} catch (Exception e) {
e.printStackTrace();
}
return obj;
}
/**
* 实体对象转成Map
* @param obj 实体对象
* @return
*/
public static Map<String, Object> object2Map(Object obj) {
Map<String, Object> map = new HashMap<String, Object>();
if (obj == null) {
return map;
}
Class clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
try {
for (Field field : fields) {
field.setAccessible(true);
map.put(field.getName(), field.get(obj));
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
@org.junit.Test
public void field2(){
Map<String,Object> map = new HashMap<String, Object>();
map.put("name","张三");
map.put("age",18);
Object r = map2Object(map, Test.class);
System.out.println(r);
Map<String, Object> stringObjectMap = object2Map(r);
System.out.println(stringObjectMap);
}
}
4.方法
//反射-调用方法示例
public class MethodDemo {
private Object getTest(){
try {
Class<?> c4 = Class.forName("com.ittest.javademo.reflection.Test");
Constructor constructor ;
Class[] classes = {int.class,java.lang.String.class};
try {
//constructor = c4.getDeclaredConstructor();
constructor = c4.getDeclaredConstructor(classes);
try {
Object aaa = constructor.newInstance(1, "aaa");
return aaa;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
//调用私有方法
@org.junit.Test
public void method1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object obj = getTest();
/**
* public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
* public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
*/
Method method = Test.class.getDeclaredMethod("doPrivate", String.class);
method.setAccessible(true);
method.invoke(obj,"aaa");
}
//前置方法
private void doPre(){
System.out.println("在方法前调用");
}
//后置方法
private void doPost(){
System.out.println("在方法后调用");
}
//案例:aop的模拟代码
public Object aop(Object obj){
doPre();
Object ret = null;
try{
Method method = Test.class.getDeclaredMethod("doPrivate", String.class);
method.setAccessible(true);
ret = method.invoke(obj,"aaa");
}catch (Exception e){
e.printStackTrace();
}finally {
doPost();
return null;
}
}
//增加前置和后置方法的调用
@org.junit.Test
public void method2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object obj = getTest();
aop(obj);
}
}