Java反射

什么是反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

反射机制的相关类

与Java反射相关的类如下:
Class类 :代表类的实体,在运行的Java应用程序中表示类和接口
Field类 :代表类的成员变量(成员变量也称为类的属性)
Method类 :代表类的方法
Constructor类 :代表类的构造方法

class类

获得类相关的方法:
getClassLoader() :获得类的加载器
getClasses(): 返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses(): 返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className): 根据类名返回类的对象
getName(): 获得类的完整路径名字
newInstance(): 创建类的实例
getPackage() :获得类的包

获得类中属性相关的方法:
getField(String name) :获得某个公有的属性对象
getFields() :获得所有公有的属性对象
getDeclaredField(String name): 获得某个属性对象
getDeclaredFields(): 获得所有属性对象

获得类中注解相关的方法:
getAnnotation(Class< A> annotationClass) :返回该类中与参数类型匹配的公有注解对象
getAnnotations(): 返回该类所有的公有注解对象
getDeclaredAnnotation(Class< A> annotationClass): 返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations(): 返回该类所有的注解对象

获得类中构造器相关的方法
getConstructor(Class…<?> parameterTypes): 获得该类中与参数类型匹配的公有构造方法
getConstructors() :获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes): 获得该类中与参数类型匹配的构造方法
getDeclaredConstructors(): 获得该类所有构造方法

获得类中方法相关的方法
getMethod(String name, Class…<?> parameterTypes): 获得该类某个公有的方法
getMethods(): 获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes): 获得该类某个方法
getDeclaredMethods(): 获得该类所有方法

Field类

Field代表类的成员变量(成员变量也称为类的属性)
equals(Object obj) :属性与obj相等则返回true
get(Object obj): 获得obj中对应的属性值
set(Object obj, Object value): 设置obj中对应属性值

Method类

Method代表类的方法。
invoke(Object obj, Object… args): 传递object对象及参数调用该对象对应的方法

Constructor类

Constructor代表类的构造方法
newInstance(Object… initargs) :根据传递的参数创建类的对象

如何获得Class对象

获得Class对象的方式:

Class.forName(“类的全限定名”)
实例对象.getClass()
类名.class (类字面常量)
Type属性

 基本类型都有type属性,可以得到这个基本类型的类型,比如:
	Class c1 = Boolean.TYPE;
	Class c2 = Byte.TYPE;
	Class c3 = Float.TYPE;
	Class c4 = Double.TYPE;

获取类的所有构造方法

	 Test test = new Test();
	 Class c4 = test.getClass();
	 Constructor[] constructors ;
	 constructors = c4.getDeclaredConstructors();

通过getDeclaredConstructors可以返回类的所有构造方法,返回的是一个数组因为构造方法可能不止一个,通过getModifiers可以得到构造方法的类型,getParameterTypes可以得到构造方法的所有参数,返回的是一个Class数组,所以我们如果想获取所有构造方法以及每个构造方法的参数类型,可以有如下代码:

	for (int i = 0; i < constructors.length; i++) {
        System.out.print(Modifier.toString(constructors[i].getModifiers()) + "参数:");
        Class[] parametertypes = constructors[i].getParameterTypes();
        for (int j = 0; j < parametertypes.length; j++) {
             System.out.print(parametertypes[j].getName() + " ");
       }
      System.out.println("");
  }

如果我们想获取有两个参数分别为int和String类型的构造方法,代码如下:

  Class[] p = {int.class,String.class};
  try {
       constructors = c4.getDeclaredConstructor(p);
       constructors.newInstance(24,"HuangLinqing");//一个实例对象
       System.out.print(Modifier.toString(constructors.getModifiers()) + "参数:");
       Class[] parametertypes = constructors.getParameterTypes();
       for (int j = 0; j < parametertypes.length; j++) {
            System.out.print(parametertypes[j].getName() + " ");
          }
       } catch (NoSuchMethodException e) {
            e.printStackTrace();
     }

那么调用私有构造方法呢,和上面一样,只是我们要设置constructors.setAccessible(true);代码如下:

  	Class[] p = {String.class};
 	constructors = c4.getDeclaredConstructor(p);
  	constructors.setAccessible(true);
  	constructors.newInstance("HuangLinqing");

我们知道如果我们要正常的调用类的方法都是通过类.方法调用,所以我们调用私有方法也需要得到类的实例,而我们上面newInstace已经得到了类的实例,这样就好办了。

	 Class[] p4 = {String.class};
	 Method method = c4.getDeclaredMethod("welcome",p4);
	 method.setAccessible(true);

我们首先通过 getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型
然后通过invoke方法执行,invoke需要两个参数一个是类的实例,一个是方法参数。

	 Class[] p4 = {String.class};
	 Method method = c4.getDeclaredMethod("welcome",p4);
	 method.setAccessible(true);
	 Object arg1s[] = {"欢迎关注代码男人技术公众号"};
	 method.invoke(test,arg1s);
	 //test类的实例当不能new 获取的时候我们也可以通过反射获取,就是上面的newInstance方法。

获取类的私有字段并修改值

看到这里你可能会说,有了set方法,什么私有不私有,test.set不就可以了,但是这里要注意我们是没有办法得到这个类的实例的,要不然都可以得到实例就没有反射一说了。我们在通过反射得到类的实例之后先获取字段:

	Field field = c4.getDeclaredField("name");
	field.setAccessible(true);
	field.set(o,"代码男人");
	//o是我们上面通过反射构造方法获取的实例
	//不过要注意的是我们修改了name的值只对当前的实例对象有效。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值