反射

作者: 开心的小哈 | 来源:发表于2021-09-04 13:32 被阅读0次

    访问构造方法

    package setDemo.hashset;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Modifier;
    
    /**
     * @outhor chenglong
     * @create 2021-08-29 21:29
     * @name 小哈
     */
    public class ConstructorDeom {
        public static void main(String[] args) {
            try {
                Class c = Class.forName("setDemo.hashset.Person");
    //            Constructor  constructors[] = c.getConstructors();//获取所有的公有的构造方法
                Constructor[] constructors = c.getDeclaredConstructors();//获取所有的构造方法
    
                for (Constructor con:constructors){
                    System.out.print(Modifier.toString(con.getModifiers())+"   ");//修饰符
                    System.out.print(con.getName()+"(");//方法名
    
                    Class[] parameterTypes = con.getParameterTypes();//方法的参数
                    for(int i=0;i<parameterTypes.length;i++){
    //                    System.out.print(parameterTypes[i].getName()+" args");//如果是String则会展示java.lang.String
                        System.out.print(parameterTypes[i].getSimpleName()+" args");//获取简化的String会展示String
                    if(i<parameterTypes.length-1){
                        System.out.print(",");
                    }
                    }
                    System.out.println("){ }");
    
                }
                Constructor decla = c.getDeclaredConstructor();//调用无参构造方法//注意存在权限限制
                //如果是私有变量则需要使用setAccessible
                decla.setAccessible(true);//获得操作权限
                Object o1 = decla.newInstance();
                System.out.println(o1.toString());
                Constructor declaredConstructor = c.getDeclaredConstructor(int.class);//调用带参的构造方法
                Object o = declaredConstructor.newInstance(123);
                System.out.println(o.toString());
                Constructor declaredConstructor2 = c.getDeclaredConstructor(int.class,String.class);//调用带参的构造方法
                Person o2 = (Person) declaredConstructor2.newInstance(123,"嘻嘻嘻");
                System.out.println(o2.toString());
    
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    
    

    访问成员变量

    package test.Ann;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    
    public class Demo2 {
        @MyAnnotation
        public static void main(String[] args) throws Exception {
            Class<?> forName = Class.forName("test.Ann.Demo");
            Field[] declaredFields = forName.getDeclaredFields();// 返回所有属性
            for (int i = 0; i < declaredFields.length; i++) {
                Field field = declaredFields[i];
                System.out.print(Modifier.toString(field.getModifiers()) + " ");// 获得访问权限
                System.out.print(field.getType().getSimpleName() + " ");// 获取属性类型,简单名称
                System.out.print(field.getName());
                System.out.println();
            }
            Constructor<?> d = forName.getConstructor();
            Demo newInstance = (Demo) d.newInstance();
            Field declaredField = forName.getDeclaredField("age");// 可以使用getDeclaredField方法来调用属性
            declaredField.setAccessible(true);// 设置属性的访问权限
            Object object = declaredField.get(newInstance);// 传入该类的对象,//通过使用Field对象的get来获取属性值
            System.out.println(object);//输出获取到的值
            System.out.println(newInstance.age);//也可以使用构造方法使用.进行调用
        }
    
    }
    
    

    访问方法

    package test.Ann;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    public class TestMain {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
                IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
    //      Class c = Class.forName("test.Ann.Demo");
    //      Constructor[] declaredConstructors = c.getDeclaredConstructors();
    //      for (int i = 0; i < declaredConstructors.length; i++) {
    //          System.out.print(Modifier.toString(declaredConstructors[i].getModifiers()) + "  ");
    //          System.out.println(declaredConstructors[i].getName());
    //      }
    
            Class c = Class.forName("test.Ann.Demo");
            Method[] declaredMethods = c.getDeclaredMethods();
            for (Method dd : declaredMethods) {
                // 获取修饰符
                System.out.print(Modifier.toString(dd.getModifiers()) + " ");
                // 输出方法的返回值
                System.out.print(dd.getReturnType().getSimpleName() + " ");// 获取方法返回参数的类型,再获取简单名称
                System.out.print(dd.getName() + "(");// 方法名
                Class<?>[] parameterTypes = dd.getParameterTypes();// 获得方法所有的参数类型
                for (int i = 0; i < parameterTypes.length; i++) {// 便利获取每一个参数
                    System.out.print(parameterTypes[i].getSimpleName() + " arg");// 获取参数类型的简单名字
                    if (i < parameterTypes.length - 1) {
                        System.out.print(",");
                    }
                }
                System.out.print(")");
                Class<?>[] exceptionTypes = dd.getExceptionTypes();// 抛出的异常类型
                if (exceptionTypes.length > 0) {
                    System.out.print(" throws ");
                }
                for (int i = 0; i < exceptionTypes.length; i++) {
                    System.out.print(exceptionTypes[i].getSimpleName());
                    if (i < exceptionTypes.length - 1) {
                        System.out.print(",");
                    }
                }
                System.out.println("{  }");
    
            }
            Constructor declaredConstructor = c.getDeclaredConstructor();// 获得构造方法
            Object newInstance = declaredConstructor.newInstance();// 调用无参构造
    
            Method declaredMethod = c.getDeclaredMethod("show", int.class, int.class);// 该方法为私有的
            declaredMethod.setAccessible(true);// 获取私有方法的权限
            declaredMethod.invoke(newInstance, 1, 2);
        }
    }
    
    

    反射注解

    前置条件需要将注解设置在jvm运行时不进行清除,允许
    1.定义一个注解类

    @Target(ElementType.FIELD) // 定义注解可以使用在什么地方,此注册只能用在成员属性上
    @Retention(RetentionPolicy.RUNTIME) // 设置在运行时保留注解
    public @interface PhoneAnntation {
        String remarks() default "";// 备注
    
        boolean enable() default true;// 属性是否启动
    }
    

    2.定义手机类使用注解功能

    package test.Ann;
    
    public class CellPhone {
        @PhoneAnntation(remarks = "品牌行该")
        public String brdMdl;// 品牌型号
        @PhoneAnntation(remarks = "价格")
        public double price;// 价格
        @Deprecated
        @PhoneAnntation(remarks = "电池接口", enable = false) // 属性不启用
        public String batteryInter;// 电池接口
        @PhoneAnntation(remarks = "厂商")
        public String produced;// 厂商
    
    }
    
    

    3.通过反射获取到注解信息并打印出来

    package test.Ann;
    
    import java.lang.reflect.Field;
    
    public class Phonetext {
        public static void main(String[] args) {
            Class s = CellPhone.class;
            Field[] declaredFields = s.getDeclaredFields();
            for (int i = 0; i < declaredFields.length; i++) {
                Field field = declaredFields[i];
                if (field.isAnnotationPresent(PhoneAnntation.class)) {// 判断该属性值是否实现此注解
                    System.out.print(field.getName() + "被注解过");// 实现了
                    PhoneAnntation p = field.getAnnotation(PhoneAnntation.class);// 获取该属性的注解
                    System.out.print(field.getName() + "属性注解为:\t");// 输出属性名字
                    System.out.print("备注:\t" + p.remarks());// 返回注解中的内容
                    System.out.println("属性是否有效" + p.enable());// 返回注解中的内容
                }
            }
        }
    }
    
    
    

    相关文章

      网友评论

          本文标题:反射

          本文链接:https://www.haomeiwen.com/subject/ssjrwltx.html