学习Java反射这一篇就够了

1.什么是反射?

​2.拿出来有什么用?

3.获取class字节码文件三种方式

4.从字节码文件里面获取构造方法、成员变量、成员方法

4.对成员变量进行操作

5.反射获取成员方法

6.获取一个类所有信息保存到文件案例

7.反射搭配配置文件,动态的创建对象,并调用方法


1.什么是反射?

反射允许对一个类的成员变量,成员方法和构造方法的信息进行编程访问,你就把反射理解成一个人它可以把类里面的东西都拿出来进行操作。

2.拿出来有什么用?

1.例如IDEA对于一个对象get还有set时,提出出来的成员变量就是这样提示出来的。

2.我们new出来的对象有时候忘记传什么形参,按住ctrl+p就能提示出来,那么IDEA就是通过反射来得到的。

3.获取class字节码文件三种方式

package com.itheima.myreflect1;
/**
 * @author JiaWei
 */
public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {

        /**
         * 获取class对象的三种方式:
         * 1. class.forName("全类名“)
         * 2. 类名.class
         * 3. 对象.getClass();
         */

        //1.包名加类名
        Class<?> class1 = Class.forName("com.itheima.myreflect1.Student");
        System.out.println(class1);

        //2.第二种方式
        Class<Student> clazz2 = Student.class;
        System.out.println(clazz2);

        //3.第三种方式
        Student s = new Student();
        Class class3 = s.getClass();


        System.out.println(class1 == clazz2);
        System.out.println(clazz2 == class3);

    }
}

4.从字节码文件里面获取构造方法、成员变量、成员方法

package com.itheima.myreflect2;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class MyReflectDemo {
    public static <Student> void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    /*
        Class类中用于获取构造方法的方法
            Constructor<?>[] getConstructors()                                返回所有公共构造方法对象的数组
            Constructor<?>[] getDeclaredConstructors()                        返回所有构造方法对象的数组
            Constructor<T> getConstructor(Class<?>... parameterTypes)         返回单个公共构造方法对象
            Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回单个构造方法对象


        Constructor类中用于创建对象的方法
            T newInstance(Object... initargs)                                 根据指定的构造方法创建对象
            setAccessible(boolean flag)                                       设置为true,表示取 消访问检查
    */

        //1.获取class字节码文件对象
        Class clazz = Class.forName("com.itheima.myreflect2.Student");

        //2.获取构造方法公有的 public
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
//            System.out.println(con);
        }
        //3.获取所有构造方法包括私有
        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con : cons2) {
//            System.out.println(con);
        }

        //4.获取单个的构造方法 默认获取共有public的无参
        Constructor con1 = clazz.getDeclaredConstructor();
//        System.out.println(con1);

        Constructor con2 = clazz.getDeclaredConstructor(String.class);
//        System.out.println(con2);
//
        Constructor con3 = clazz.getDeclaredConstructor(int.class);
//        System.out.println(con3);

        Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);
//        System.out.println(con4);

        int modifiers = con4.getModifiers();
//        System.out.println(modifiers);

        //5.获取所有参数类型 作用就是IDEA传参按住ctrl+p显示参数类型一样
        Parameter[] parameters = con4.getParameters();
        for (Parameter parameter : parameters) {
//            System.out.println(parameter);
        }
        
        //6.暴力反射:表示临时取消权限校验
        con4.setAccessible(true);
        Student stu = (Student) con4.newInstance("张三", 23);

        System.out.println(stu);
    }
}

4.对成员变量进行操作

package com.itheima.myreflect3;

import java.lang.reflect.Field;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
    /*
       Class类中用于获取成员变量的方法
            Field[] getFields():                返回所有公共成员变量对象的数组
            Field[] getDeclaredFields():        返回所有成员变量对象的数组
            Field getField(String name):        返回单个公共成员变量对象
            Field getDeclaredField(String name):返回单个成员变量对象

       Field类中用于创建对象的方法
            void set(Object obj, Object value):赋值
            Object get(Object obj)              获取值

    */
        //1.获取class字节码文件的对象
        Class clazz = Class.forName("com.itheima.myreflect3.Student");

        //2.获取所有的成员变量 无论共有私有
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
//            System.out.println(field);
        }
        //3.获取指定共有的成员变量
        Field gender = clazz.getField("gender");
//        System.out.println(gender);

        //4.获取指定私有的成员变量
        Field name = clazz.getDeclaredField("name");
//        System.out.println(name);

        //5.获取权限修饰符 私有的为2
        int modifiers = name.getModifiers();
//        System.out.println(modifiers);

        //6.获取成员变量名称
        String nameName = name.getName();
//        System.out.println(nameName);

        //7.获取成员变量数据类型
        Class<?> type = name.getType();
        System.out.println(type);

        //8.获取成员变量记录的值
        Student s = new Student("zhangsan",23,"男");
        name.setAccessible(true);
        Object value = name.get(s);
//        System.out.println(value);


        //9.修改对象里面记录的值
        name.set(s,"lisi");
        System.out.println(s);
    }
}

5.反射获取成员方法

package com.itheima.myreflect4;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    /*
       Class类中用于获取成员方法的方法
            Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的
            Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
            Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
            Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象


       Method类中用于创建对象的方法
            Object invoke(Object obj, Object... args):运行方法
            参数一:用obj对象调用该方法
            参数二:调用方法的传递的参数(如果没有就不写)
            返回值:方法的返回值(如果没有就不写)

        获取方法的修饰符
        获取方法的名字
        获取方法的形参
        获取方法的返回值
        获取方法的抛出的异常

    */
        //1. 获取class字节码文件对象
        Class clazz = Class.forName("com.itheima.myreflect4.Student");

        //2.获取里面所有的方法对象也就是equals或者hashCode(包含父类中所有的公共方法,且不包含私有的)
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }

        //3.获取里面所有的方法对象(不能获取父类的,但是可以获取本类中私有的)
//        Method[] methods = clazz.getDeclaredMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }

        //4.获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat",String.class,int.class);
//        System.out.println(m);

        //5.获取方法的修饰符 2为私有的private
        int modifiers = m.getModifiers();
//        System.out.println(modifiers);

        //6.获取方法的名字
        String name = m.getName();
//        System.out.println(name);

        //7.获取方法的形参类型
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
//            System.out.println(parameter);
        }

        //8.获取方法抛出的异常
        Class[] exceptionTypes = m.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
//            System.out.println(exceptionType);
        }

        //9.通过反射将指定类的方法参数进行修改
        //s 表示方法的调用者 汉堡包表示在调用方法的时候传递的实际参数
        Student s = new Student();
        m.setAccessible(true);
        String result = (String) m.invoke(s, "汉堡包");
        System.out.println(result);

    }
}

6.获取一个类所有信息保存到文件案例

package com.itheima.myreflect5;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;

public class MyReflectDemo {
    public static void main(String[] args) throws IllegalAccessException, IOException {
    /*
        对于任意一个对象,都可以把对象所有的字段名和值,保存到文件中去
    */
        Student s = new Student("小A", 23, '女', 167.5, "睡觉");
        Teacher t = new Teacher("播妞", 10000);
        saveObject(s);
    }

    public static void saveObject(Object obj) throws IllegalAccessException, IOException {
        //1.获取字节码文件的对象
        Class clazz = obj.getClass();

        BufferedWriter writer = new BufferedWriter(new FileWriter("D:\\网络编程\\代码\\myreflect\\myreflect\\a.txt"));

        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            //获取成员变量的名字
            String name = field.getName();
            //获取成员变量的值
            Object value = field.get(obj);
            writer.write(name + "=" + value);
            writer.flush();
            writer.newLine();
        }
        writer.close();

    }
}

7.反射搭配配置文件,动态的创建对象,并调用方法

package com.itheima.myreflect6;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class MyReflectDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    /*
        反射可以跟配置文件结合的方式,动态的创建对象,并调用方法
    */
        //1.读取配置文件信息
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream("D:\\网络编程\\代码\\myreflect\\myreflect\\prop.properties");
        prop.load(fis);
        fis.close();
//        System.out.println(prop);

        //2.获取全类名和方法名
        String className = (String) prop.get("classname");
        String methodName = (String) prop.get("method");

//        System.out.println(className);
//        System.out.println(methodName);

        //3.利用反射创建对象并运行方法
        Class clazz = Class.forName(className);

        //4.获取构造方法
        Constructor con = clazz.getDeclaredConstructor();
        Object o = con.newInstance();
//        System.out.println(o);

        //获取成员方法并运行
        Method method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true);
        method.invoke(o);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值