反射

java.lang.reflect.*
一个类被加载后,JVM会创建一个对应该类的Class对象,类的整个结构信息会放到对应的Class对象中,一个类只对应一个Class对象。

一.Class对象的获取

1.Class.forName(String path)
2.类.class
3.对象.getClass()

二.获取类的信息

1.类名

String getName(); 包名+类名
String getSimpleName(); 类名

2.属性Field

Field getField(String fieldName); 获取Field,必须是public
Field getDeclaredField(String field); 获取Field
Field[] getFields(); 获取public Field数组
Field[] getDeclaredFields(); 获取Field数组

3.方法Method

Method getMethod(String methodName,paramType.class...|null);

4.构造器Constructor

Constructor getConstructor(paramType.class...|null);

5.注解

getAnnotation(Annotaion1.class);

6.泛型

	public class Demo03 {

		public void test01(Map<String,Integer> map,List<String> list) {
			System.out.println("Demo3.test01()");
		}
		
		public Map<String, Integer>test02(){
			System.out.println("Demo03.test02()");
			return null;
		}
		
		public static void main(String[] args) {
			try {
				System.out.println("-------------(1)获取指定方法 参数 的泛型信息----------------------");
				Method m=Demo03.class.getDeclaredMethod("test01", Map.class,List.class);
				Type[] types=m.getGenericParameterTypes();
				for(Type paramtype:types) {
					System.out.println(paramtype);
					if(paramtype instanceof ParameterizedType) 
						Type[] genericTypes=((ParameterizedType)paramtype).getActualTypeArguments();
						for(Type genericType:genericTypes) {
							System.out.println("参数泛型类型"+genericType);
						}
					}
				}
				System.out.println("--------------------------------------------------------------");
				System.out.println("-------------(2)获得方法 返回值 的泛型信息----------------------------");
				Method m2=Demo03.class.getDeclaredMethod("test02", null);
				Type returnType=m2.getGenericReturnType();
                                System.out.println(returnType);
				if(returnType instanceof ParameterizedType) {
					Type[] genericTypes=((ParameterizedType)returnType).getActualTypeArguments();
					for(Type genericType:genericTypes) {
						System.out.println("返回值泛型类型:"+genericType);
					}
				}
				System.out.println("------------------------------------------------------------------------");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

三.通过反射API动态操作构造器、方法、属性

Class clas=(Class) Class.forName("Reflect.Test");

1.通过反射调用构造方法,构造对象

//调用无参构造器
Test test=clas.newInstance();
//调用带参构造器
Constructor c=clas.getDeclaredConstructor(int.class,String.class);
Test test1=c.newInstance(19,"lala");

2.调用普通方法

Test test2=clas.newInstance();
Method method=clas.getDeclaredMethod("func01",String.class);
method.invoke(test2, "张三");
//等同于test2.func01("张三");//方便 动态加载类,动态调用方法

3.操作属性

Test test3=clas.newInstance();
Field f=clas.getDeclaredField("name");
f.setAccessible(true);//设置属性不需要做安全检查,直接可以访问
f.set(test3, "sd");

使用反射运行速度较慢,使用setAccessible(true)跳过安全检查,可以加快反射。

posted @ 2020-01-15 10:00  赵钱富贵  阅读(124)  评论(0编辑  收藏  举报