java反射机制

java反射机制

java反射机制可以让我们在运行期获取类、接口、变量和方法的信息。通过反射我们可以动态的创建对象,获取类的属性(包括私有属性)、方法等信息;通过反射我们亦可以实现动态代理、动态的类加载以及与泛型相关的操作。

获取类

获取class对象

在获取一个类的相关信息前,我们必须首先获取它的class对象,这里有两种方式:

  1. 直接通过Object.class,如下:

    Class myClass = MyObject.class;
    
  2. 通过一个类的权限定名

    Class myClass = Class.forName("com.xxx.MyObject");
    

获取类名

获取类名有两种,一种是获取类的全限定名,也就是带有包路径,另一种直接是类名。

  1. 获取类的权限定名

    Class myClass = MyObject.class;
    String className = myClass.getName();
    
  2. 获取类名

    Class myClass = MyObject.class;
    String className = myClass.getSimpleName();
    

获取访问修饰符

通过反射可以获取类的访问修饰符,如public,private或static等

    Class class = ....//获取class对象
    int modifiers = class.getModifiers();

访问修饰符被包装成int类型,可以通过以下防范判断是哪个类型的修饰符.

    Modifier.isAbstract(int modifiers);
    Modifier.isFinal(int modifiers);
    Modifier.isInterface(int modifiers);
    Modifier.isNative(int modifiers);
    Modifier.isPrivate(int modifiers);
    Modifier.isProtected(int modifiers);
    Modifier.isPublic(int modifiers);
    Modifier.isStatic(int modifiers);
    modifier.isStrict(int modifiers);
    Modifier.isSynchronized(int modifiers);
    Modifier.isTransient(int modifiers);
    Modifier.isVolatile(int modifiers);

获取父类

    Class class = ....//获取class对象
    Class superClass = class.getSuperClass();
    String superName = superClass.getName();
    ...

获取实现的接口集合

    Class class = ....//获取class对象
    Class[] interfaces = class.getInterfaces();

获取方法数组

    Class class = ...//获取class对象
    Method[] methods = class.getMethods();

获取字段集合

    Class class = ...//获取class对象
    Field[] fields = class.getFields();

获取注解

    Class class = ...//获取class对象
    Annotation[] annotation = class.getAnnotations();

创建对象

创建对象大体有两种方式:

  1. 直接利用class对象的newinstance()方法

    Class class = ....//获取class对象
    MyObject myObject = (MyObject)class.newInstance();
    myobject.setXXX("xxxx");
    ...
    
  2. 先获取类的构造器,然后通过构造方法去实例化一个对象

    Class class = ....//获取class对象
    //返回一个构造方法的集合
    Construct<?>[] constructs = class.getConstructs();
    //这里是调用默认的构造方法来实例化对象
    MyObject myObject1 = constructs[0].newInstance();
    myObjecy1.setXXX("xxx");
    //调用有参构造方法
    MyObject myObject2 = constructs[1].newInstance(33,"haha");
    
    //by the way 通过构造方法也可以获取到构造方法的参数信息 如参数名、参数的修饰符,如int、string等
    Class[] paramTypes = constructs[1].getParamTypes(); //这是一个参数的对象数组
    for(Class parameterType:parameterTypes) {
            System.out.println(parameterType.getSimpleName());
            //获取修饰符
            System.out.println(parameterType.getModifiers());
        }
    

获取变量

获取Field对象

    Class class = ....//获取class对象
    //获取变量字段的集合
    Field[] fields = class.getFields();
    for(Field field:fields) {
        System.out.println(field.getName());
    }
    //注意:这种方式只能获取共有变量

获取私有变量

    //要想获取私有变量,可以通过下面这个方法
    Class class = ....//获取class对象
    MyObject myObject = (MyObject)class.newInstance();
    Field privateField = myObject.getDeclaredField("私有变量名");
    privateField.setAccessible(true); //必须要有这句话,他会关闭指定类Field实例的反射访问检查
    System.out.println(privateField.getName());

修改变量

    //接着上面的代码
    privateField.set(myObject,"ddddd"); //修改刚才获取的变量的内容

获取方法

获取指定的方法

    //如果已知方法的名字及参数则可通过下面方式获取该方法
    Class  aClass = ...//获取Class对象
    //第一个参数为方法名,第二个参数为该方法的参数
    Method method = aClass.getMethod("doSomething", new Class[]{String.class});

通过方法对象调用其他方法

    Class  aClass = MyObject.class//获取Class对象
    Method method = aClass.getMethod("doSomething", new Class[]{String.class});
    //第一个参数为一个对象 当主调方法为静态方法时传null即可,若不是则需要传MyObject对象实例
    Object returnValue = method.invoke(null,"参数");

获取方法参数及返回类型

    Class  class = ...//获取Class对象
    Method method = class.getMethod("","");
    Class[] paramterTypes = method.getParameterTypes();
    //获取返回值
    Class returnType = method.getReturnType();

泛型

获取方法泛型的返回类型

    class MyClass {
        private List<String> list;
        public List<String> getStringList() {
            return this.list;
        }
        public void getStringList(List<String> list,Map<String,String> map) {
            this.list = list;
        }
    }

    //获取指定的方法
    Method method = MyClass.class.getMethod("getStringList",null);
    //获取该方法返回的类型对象
    Type returnType = method.getGenericReturnType();
    System.out.println(returnType+"");
        if(returnType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType)returnType;
            //该返回类型对象的参数结合
            Type[] typeArguments = parameterizedType.getActualTypeArguments();
            for(Type typeArgument:typeArguments) {
                Class typeArgClass = (Class) typeArgument;
                System.out.println("typeArgClass--"+typeArgClass);
            }
        }
    //输出结果:
    java.util.List<java.lang.String>
    typeArgClass--class java.lang.String

获取方法参数的类型

    //与获取返回类型大同小异
    Method method2 = MyClass.class.getMethod("getStringList", List.class,Map.class);
        Type[] genericParameterTypes = method2.getGenericParameterTypes();
        for(Type genericParameterType:genericParameterTypes) {
            System.out.println("genericParameterTypes--"+genericParameterType);
            if(genericParameterType instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
                Type[] parameterArgTypes = parameterizedType.getActualTypeArguments();

                for(Type parameterArgType:parameterArgTypes) {
                    System.out.println("parameterArgTypes--"+parameterArgType);
                    Class typeClass = (Class) parameterArgType;
                    System.out.println("parameterArgClass--"+typeClass);
                }
            }
        }

数组

通过反射创建一个数组

    //创建一个整形数组 第一个参数为类型的class对象、第二个对象为数组大小
    int[] intArray = (int[]) Array.newInstance(int.class, 3);

设置数组值

    Array.set(intArray, 0, 1);
    Array.set(intArray, 1, 2);
    Array.set(intArray, 2, 3);

访问数组

    System.out.println(Array.get(intArray, 1));
    System.out.println(Array.get(intArray, 2));

获取数组的成员类型

    String[] strings = new String[3];
    Class classl = strings.getClass();
    Class type = classl.getComponentType();
    System.out.println(type);
    //结果
    class java.lang.String

参考http://ifeve.com/java-reflection/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值