反射冠军宝座

1.概念:

 Java反射机制可以让我们在编译期之外的运行期检查类,接口,变量以及方法的信息.
 反射还可以让我们在运行实例对象,调用方法,通过调用get/set方法获取变量的值.
 反射机制中可以在程序中访问已经加载到JVM中java对象的描述,实现访问,
 检测和修改描述java对象本身的信息的功能

2.反射的运用:

  使用java反射机制可以在运行时期检查java类的信息,
  通过获取类的信息你可以获取以下相关的内容:Class对象,类名,
  修饰符,包信息,父类,实现接口,构造器,方法,变量,注解等等.

1.Class对象
获取类的字节码对象有三种方式:
类名.class
Class.forName(包名+类名)
实例对象.getClass();
实例如下:

     package myproject2;
 * 测试反射的方法
 * @author renjiaxing
public class TestReflectMethod {
         public static void main(String[] args) {
        	 //Class<?> aClass=class1.class;
        	  //Class<?>aClass= new class1().getClass();
			try {
				Class<?>aClass = Class.forName("myproject2.class1");

2.类名
可以使用获取的字节码对象获取类名(这里有两种形式)
一种是获取类的全限定名名称(包名+类名):getName()
另一种是获取类的名称(不包含包名):getSimpleName()
实例如下:

				Class<?>aClass = Class.forName("myproject2.class1");
				String className = aClass.getName();
				   String simpleName = aClass.getSimpleName();
				System.out.println(className);
				System.out.println(simpleName);

3.修饰符
可以通过字节对象来访问一个类的修饰符,即public,private,static等等的关键字
你可以使用如下方法 getModifiers()如图:
这里注意:getModifiers()返回的是一个int类型,还需要使用import java.lang.reflect.Modifier;中的方法验证是哪个修饰符.

     				    int modifiers = aClass.getModifiers();
				    Modifier modifier = new Modifier();
				    boolean pubtype = modifier.isPublic(modifiers);
				    System.out.println(pubtype);

4.包信息
使用字节码对象通过以下方法来获取包信息:getPackage()
代码如下:

 	Class<?>aClass = Class.forName("myproject2.class1");
				Package packageName = aClass.getPackage();
				System.out.println(packageName);

5.父类
通过字节码对象获取类的父类对象(如果业务需要还可以在父类基础上继续反射)

   	Class<?>aClass = Class.forName("myproject2.class1");
				 Class<?> supClass = aClass.getSuperclass();
				System.out.println(supClass);

6.实现的接口
通过字节码对象获取实现的接口.由于一个类可以实现很多的接口,因此getInterfaces()返回的是一个Class<?>数组,注意:仅仅是只返回了当前类实现的接口,父类的实现的接口不会返回.尽管实际上当前类已经实现了父类的接口.

		Class<?>aClass = Class.forName("myproject2.class1");
				 Class<?>[] interfaces = aClass.getInterfaces();
				 System.out.println(interfaces);

7.构造方法
通过字节码对象获取每一个公开的(public)的构造方法,以及获取指定参数的构造方法,获取构造方法的参数,利用构造方法实例化一个类,代码如下:

 			try {
				Class<?>aClass = Class.forName("myproject2.class1");
				Constructor<?>[] constructors = aClass .getConstructors();
				for (Constructor<?> constructor : constructors) {
					System.out.println(constructor);
				}
				Constructor<?> constructor= aClass.getConstructor(new Class[]{int.class});
				System.out.println(constructor);
				Parameter[] parameters = constructor.getParameters();
				Class<?>[] parameterTypes = constructor.getParameterTypes();
				for (Parameter parameter : parameters) {
					System.out.println(parameter);
				}
				for (Class<?> class1 : parameterTypes) {
					System.out.println(class1);
				}
				Object newInstance = constructor.newInstance(123);
				System.out.println(newInstance);

8.变量
使用反射机制,可以在运行期检查一个类的成员变量获取或者设置变量的值.注意这里变量修饰符的权限问题;

			Class<?>aClass = Class.forName("myproject2.class1");
				 Field[] fields = aClass .getFields();//获取修饰符为public的
				 Field field = aClass.getField("a");
				 System.out.println(field.getName());
				 System.out.println(field .getType());
				 class1 myClass1 = (class1) aClass.newInstance();
				 Object fieldObject = field.get(myClass1);
				 field.set(myClass1, fieldObject);
         
              Field field = aClass.getDeclaredField("b");获取private的成员变量
		          field.setAccessible(true);这行代码关闭访问检查
				 class1 myClass1 = (class1) aClass.newInstance();
//用字节码获取一个实例对象
				   String  fieldObject =(String) field.get(myClass1);
				   field .set(myClass1, fieldObject);

9.方法
方法与变量同样的要考虑修饰符的问题

	Class<?>aClass = Class.forName("myproject2.class1");
				Method[] methods = aClass.getMethods();
			  Method method = aClass.getMethod("a", new Class[]{String.class});
			  System.out.println(method);
			  Class<?>[] parameterTypes = method.getParameterTypes();
			  for (Class<?> class1 : parameterTypes) {
				System.out.println(class1);
			}
			  Class<?> returnType = method.getReturnType();
			  System.out.println(returnType);
			 
			  class1 myClass1=(class1) aClass.newInstance();
			  method.invoke(myClass1, "String[]");//如果是静态方法的话就用null
			  
			  Method declaredMethod = aClass.getDeclaredMethod("b", new Class[]{String.class});
			  System.out.println(declaredMethod);
			  declaredMethod.setAccessible(true);
			  class1 class2= (class1) aClass.newInstance();
				method.invoke(null, "String[]");

10.注解
通过字节码反射获取类上的注解,方法上的注解,属性上的注解,以及参数的注解

  	Class<?>aClass = Class.forName("myproject2.class1");
				   获取类上的注解
 Annotation[] annotations = aClass.getAnnotations();
				   Myanno annotation = aClass.getAnnotation(Myanno.class);
				   
				   获取方法上的注解
				   Method method = aClass.getMethod("a", new Class[]{String.class});
				   Annotation[] annotations2 = method.getAnnotations();
				   Myanno annotation2 = method.getAnnotation(Myanno.class);
				   System.out.println(annotation2);
               获取方法参数的注解
			Annotation[][] parameterAnnotations = method.getParameterAnnotations();	
			    	 Class<?>[] parameterTypes = method.getParameterTypes();
			         int i=0;
			         for (Annotation[] annotations3 : parameterAnnotations) {
			        	 Class<?> parameter = parameterTypes[i++];
			        	 for (Annotation annotation4 : annotations3) {
							if (annotation4 instanceof Myanno) {
								 Myanno myanno=(Myanno) annotation4;
								 System.out.println(parameter.getName());
								 System.out.println(myanno.name());
								System.out.println(myanno.value());
							}
						}
					}
                    获取成员变量属性的注解
			         Field field = aClass.getField("a");
			         Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
			     Myanno declaredAnnotation = field.getDeclaredAnnotation(Myanno.class);

11.反射还可以使用在泛型擦除,数组的处理(使用java.lang.reflect.Array来处理),动态代理…后期会续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值