反射

2021-09-04  本文已影响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());// 返回注解中的内容
            }
        }
    }
}


上一篇下一篇

猜你喜欢

热点阅读