java反射的认知和学习

1.学习了Class对象,Filed对象(对应数据),Method对像(对应函数),Constructor对象(对应构造函数)。

2.Declared可用于获取私有的数据和方法,但是打印得使用setAccessible(true);来要忽略访问权限修饰符的检查。

3.FS5()函数有一个点需要注意就是地址一致,原因我写在注释里了。

#FS练习配置文件
#1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
#2.在程序中加载读取配置文件
#3.使用反射技术来加载类文件进入内存
#4.创建对象
#5.执行方法
#
#
className=bean.Admin 
methodName=eat

Filed对象的学习

  

 /**
     * 学习java反射机制
     * Field对象的学习
     */
    @Test
    public void FS1() throws NoSuchFieldException, IllegalAccessException {
        Class userClass = User.class;

        Field[] fields = userClass.getFields();//获取所有public的成员对象
        for(Field field:fields)
        {
            System.out.println(field);
        }

        Field field1 =userClass.getField("fs");//按照变量名获取

        /*
          Field 操作
          1.设置
          set
          2.获取
          get
         */
        User user1=new User();
        System.out.println(field1.get(user1));
        field1.set(user1,"dada");
        System.out.println(field1.get(user1));

        //忽略修饰符 可以获取到私有的
        Field[] full=userClass.getDeclaredFields();
        for(Field field:full)
        {
            System.out.println(field);
        }
        //获取单个某一个 忽略修饰符
        Field privateField=userClass.getDeclaredField("id");
        //但是打印私有的,需要忽略访问权限修饰符的检查
         privateField.setAccessible(true);  //暴力反射
        System.out.println(privateField.get(user1));
    }

Constructor对象的学习

 /**
     * 反射机制获取构造方法
     */
    @Test
    public  void FS2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class userClass = User.class;
        //获取所有的
        Constructor[] constructors=userClass.getConstructors();
        for(Constructor constructor:constructors)
        {
            System.out.println(constructor);
        }
        //获取单个
        Constructor constructor =userClass.getConstructor(Integer.class,String.class);
        System.out.println(constructor);

        //使用获取的constructor创建对象
        Object user =constructor.newInstance(5,"dada");
        System.out.println(user.toString());

        /*
         使用空参的构造方法
         */
        Constructor constructor1 =userClass.getConstructor();
        System.out.println(constructor);
        Object user1 =constructor1.newInstance();
        System.out.println(user1.toString());
        System.out.println("与上同理");
        //与上同理,Class这个方法就是为了方便调用空参的构造方法
        Object user2=userClass.newInstance();
        System.out.println(user2.toString());

        //暴力反射constructor.setAccessible();
    }

 Method对象的学习

 /**
     * 反射机制获取方法
     * Method
     */
    @Test
    public void FS3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class userClass = User.class;

        //获取类名
        String className =userClass.getName();
        System.out.println(className);
        //获取public所有方法
        Method[] methods = userClass.getMethods();
        for (Method method:methods)
        {
            //也会打印Obj里的方法
            System.out.println(method);
            //获取方法名
            System.out.println(method.getName());
        }
       // 获取方法 根据方法名 返回值
        Method eat = userClass.getMethod("eat");
        Method eat1= userClass.getMethod("eat",int.class);
        User user=new User();
        eat.invoke(user);//执行方法
        eat1.invoke(user,1);//执行方法



    }

 配置文件和反射的使用

 /**
     *配置文件和反射的使用
     */
    @Test
    public void FS4() throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.加载配置文件
        Properties pro =new Properties();
        //获取classes目录下的配置文件  ClassLoader类
        ClassLoader classLoader=TestUserFS.class.getClassLoader();
        //获取输入流
        InputStream resourceAsStream = classLoader.getResourceAsStream("FS.properties");
        //加载
        pro.load(resourceAsStream);

        //2.获取配置文件中定义的数据
        String className =pro.getProperty("className");
        String methodName =pro.getProperty("methodName");
        System.out.println(methodName);
        //3.加载类进内存
        Class userClass = Class.forName(className);
          //4.创建对象
        Object obj=userClass.newInstance();
        //5.获取对象方法
         Method method=userClass.getMethod(methodName);
         //获取带参数的那个eat函数
        Method method1=userClass.getMethod(methodName,int.class);
         //6.执行方法
         method.invoke(obj);
        method1.invoke(obj,1);
    }

三种常用的方法: Class.forName()函数,我在用JDBC的时候用到过,其他俩种很少。

 /**
     * 笔记
     * 1.Class.forName("全类名")
     * 2.对象.getClass():方法获取
     * 3.类名.class:通过类名的属性class获取
     */
    @Test
    public void FS5() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //1用于配置文件中
        Class objClass1= Class.forName("bean.User");
        System.out.println(objClass1);
        Object user1=objClass1.newInstance();
        Method method1=objClass1.getMethod("eat");
        method1.invoke(user1);

        //2.用于现有对象的获取字节码
        Class objClass2=User.class;
        System.out.println(objClass2);

        //3.用于参数传递
        User user3=new User();
        Class objClass3=user3.getClass();
        System.out.println(objClass3);

        /*
         * 三个是相同的地址
         * 为什么呢?
         * 因为class加载进内存后只会一次,所以你获取他的时候只有一个
         */
        System.out.println(objClass1.hashCode());
        System.out.println(objClass2.hashCode());
        System.out.println(objClass3.hashCode());
    }

 总结:java的反射机制和配置文件真的太好用了,就我之前学习的log4的配置在控制台错误输出对我帮助很大。

java的Junit让我写代码越来越方便。

 

猜你喜欢

转载自www.cnblogs.com/gonT-iL-evoL-I/p/11727809.html
今日推荐