Java 反射-超快速入门


一、反射及作用

  1、什么是 反射(Reflect)👻

1、反射( Reflect | /rɪˈflekt/ )是在运动时动态访问类与对象的技术|
2、反射是JDK1.2版本后的高级特性,隶属于java.lang.reflect|
3、大多数Java框架都基于反射实现参数配置、动态注入等特性|
4、在运行时 动态创建对象 执行方法 访问成员变量

    运动时动态访问类与对象——>>> 代码演示🚴🚴🚴

//				  在不改变源代码的情况下,创建新的 类 动态加载该类 并使用该 类
//1.定义一个四则运算 接口
public interface YunSuan{
	public float function(int x , int y);
}
//2.创建 相加 的 类  实现上面的接口  实现接口方法
public class Add implements YunSun {
    @Override
    public float function(int a , int b) {
        return a + b;
    }
}
//3.              测试类
public class Test {
    public static void main(String[] args) {
        EZ();
    }

    //创建测试方法  再  利用反射 创建对象
    public static void EZ(){
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入计算类名:");
        String LOL = scanner.next();
        System.out.print("请输入a:");
        int a = scanner.nextInt();
        System.out.print("请输入b:");
        int b = scanner.nextInt();
                                   //获取某一个类                      创建 获取 类的对象
        YunSun YS = (YunSuan) Class.forName("zzz.yyy.xxx." + LOL).newInstance();
        //控制台可以显示结果
        System.out.println(YS.function(a, b));
    }   
}

两数相加:使 LOL = Add 即可。总结:代码没写死 LOL的值是动态的。若添加 四则运算 其他功能 无需改上面的代码,只要 创建相应的类即可。| 例:两数相减:创建同路目录下 相减的 并实现接口方法即可。



二、Class核心方法

Class.forName()                  静态方法     用于获取指定Class对象   例如获取到之后 是 =》classObj

classObj.newInstance()                  通过 默认 构造方法创建新建的对象 返回Object所以下面强转了

classObj.getMethod()                  获取指定的public修饰方法Method对象

classObj.getField()                  获取指定的public修饰成员变量Field对象

    相关 代码演示如下: 👇 👇 👇

  1、Class 类

Class对象 是描述 其他 的 一个对象 那么Class就是…  (    真玄乎~    )

public class Employee {
    private Integer eno;
    public String ename;
    private Float salary;
    private String dname;

        //简洁效果 此处省略 
        //无参构造、带参构造
        //set \ get 方法 
        // toString
    public Employee function(Float val){
    this.salary = this.salary + val;
    System.out.println(this.ename + "调薪至" + this.salary + "元");
    return this;
    }
}

Class.forName()                  静态方法     用于获取指定Class对象   例如获取到之后 是 =》classObj

classObj.newInstance()                  通过 默认 构造方法创建新建的对象 返回Object所以下面强转了

public class Test {
    public static void main(String[] args) {
        try {
            //Class.forName()方法将指定的类加载到jvm,并返回对应Class对象
            Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
            System.out.println("Employee已被加载到jvm");
            //newInstance通过默认构造方法创建新的对象
            Employee emp = (Employee)employeeClass.newInstance();
            System.out.println(emp);//可以得到一个对象
        } catch (ClassNotFoundException e) {
            //类名与类路径书写错误是抛出"类无法找到"异常
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            //非法访问异常,当在作用域外访问对象方法或成员变量时抛出
            e.printStackTrace();
        } catch (InstantiationException e) {
            //对象无法被实例化,抛出"实例化异常"
            e.printStackTrace();
        }
    }
}

  2、 Constructor构造方法类

classObj.getConstructor()                  获取指定的public修饰构造方法Constructor对象 例如获取到之后 是 =》constructorObj

constructorObj.newInstance()                  通过 对应 的构造方法创建对象

public class ConstructorSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    //  .class    =》
                    Integer.class,String.class,Float.class,String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    007,"终结者",2500f,"未来世界"
            });
            System.out.println(employee);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            //没有找到与之对应格式的方法
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            //当被调用的方法的内部抛出了异常而没有被捕获时
            e.printStackTrace();
        }
    }
}

  3、 Method方法类

classObj.getMethod()                  获取指定的public修饰方法Method对象 例如获取到之后 是 =》methodObj

methodObj.invoke()                  调用指定对象的对应方法

public class MethodSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class,String.class,Float.class,String.class
            });
            Employee employee = (Employee)constructor.newInstance(new Object[]{
                    007,"终结者",3000f,"未来世界"
            });
            Method updateSalaryMethod = employeeClass.getMethod("function" , new Class[]{
                    Float.class
            });
            Employee employee1 = (Employee)updateSalaryMethod.invoke(employee,new Object[]{1000f});
            System.out.println(employee1);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

  4、 Field成员变量类

classObj.getField()                  获取指定的public修饰成员变量Field对象 例如获取到之后 是 =》fieldObj

fieldObj.set()                  为某对象指定成员属性赋值

fieldObj.get()                  获取某对象指定成员变量数值

public class FieldSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class,String.class,Float.class,String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    007,"终结者",3000f,"未来世界"
            });
            Field enameField = employeeClass.getField("ename");
            enameField.set(employee,"幽灵猎手");
            String ename = (String)enameField.get(employee);
            System.out.println("ename:" + ename);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            //没有找到对应成员变量时抛出的异常
            e.printStackTrace();
        }
    }
}

  5、 getDeclared系列方法说明

可以获取所有的修饰符对象,当对私有的 进行访问或调用会抛出无法访问的异常

getDeclaredConstructor(s)|Method(s)|Field(s)获取对应对象

public class getDeclaredSample {
    public static void main(String[] args) {
        try {
            Class employeeClass = Class.forName("zzz.yyy.xxx.aaa.Employee");
            Constructor constructor = employeeClass.getConstructor(new Class[]{
                    Integer.class, String.class, Float.class, String.class
            });
            Employee employee = (Employee) constructor.newInstance(new Object[]{
                    007,"终结者",3000f,"未来世界"
            });
            //获取当前类所有成员变量
            Field[] fields = employeeClass.getDeclaredFields();
            for(Field field : fields){
//                System.out.println(field.getName());
                if(field.getModifiers() == 1){ //pubilc修饰
                    Object val = field.get(employee);
                    System.out.println(field.getName() + ":" + val);
                }else if(field.getModifiers() == 2){ //private修饰
                    String methodName = "get" + field.getName().substring(0,1).toUpperCase()
                                        + field.getName().substring(1);
                    Method getMethod = employeeClass.getMethod(methodName);
                    Object ret = getMethod.invoke(employee);
                    System.out.println(field.getName() + ":" + ret);
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}


总结

  侧重点在于反射的主要流程,能快速认识反射。粗略总结以上内容。码字不易,如果对您有所帮助不妨留个赞赞~🐬🐬🐬

       我爱你 ~  有时候我希望你的一生,能被拍成一部漫长的电影,我就比你晚出生一百年,一辈子只做一件事,独自坐在房间里对着墙上的屏幕,用我的一生把你的一生慢慢看完。💕💕💕


                     🙏愿: 宇宙的尽头没有 反射。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值