java的反射机制



前言

java反射机制的理解与运用


提示:以下是本篇文章正文内容,下面案例可供参考

一、反射是什么?

简单的来说反射就是把Java类中的各个部分如方法、变量、构造器等映射称一个对象

1、Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于 Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

2、加载完类之后,在堆内存的方法区中就产生了一个clas类型的对象(一个类只有一个Cass对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

二、通过声明 xxx 类所在包的完整名完成反射操作

1、反射访问构造方法

1.1要被访问构造方法的类声明如下

package lesson20210629;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Student {
    /**
     * 构造方法
     */
    public Student() {//无参构造方法
        System.out.println("这里是无参构造方法");
    }
    public Student(String name){//有参构造方法
        System.out.println("名称为"+name);
    }
    public Student(String name,int age){//不同参数构造方法
        System.out.println("名称为"+name+",年龄为:"+age);
    }
    private  Student(int age){//私有属性构造方法
        System.out.println("私有年龄为"+age);
    }
}

1.2、访问无参构造方法

public static void method01(String addr){
        //路径:lesson20210629/Student
        try {
            Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
            System.out.println(clazz);
            Constructor cs = clazz.getConstructor();//获取到构造方法
            Student s = (Student) cs.newInstance();//通过无参构造创建


        }catch (Exception e){
            e.printStackTrace();
        }
    }

1.3访问有参构造方法

 public static void method02(String addr){
        //路径:lesson20210629/Student
        try {
            Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
            System.out.println(clazz);
            Constructor cs = clazz.getConstructor(String.class,int.class);//获取到构造方法
            Student s = (Student) cs.newInstance("qn",18);//通过有参构造创建

        }catch (Exception e){
            e.printStackTrace();
        }
    }

1.3、访问私有的参构造方法

 public static void method03(String addr){
        //路径:lesson20210629/Student
        try {
            Class clazz = Class.forName(addr);//代表Student类在内存中的字节码对象
            System.out.println(clazz);
            Constructor cs = clazz.getDeclaredConstructor(int.class);//获取到私有化构造方法
            cs.setAccessible(true);//暴力反射
            Student s = (Student) cs.newInstance(20);//通过有参构造创建


        }catch (Exception e){
            e.printStackTrace();
        }
    }

1.4、main方法

public class Test01 {
    public static void main(String[] args) {
        method01("lesson20210629.Student");
        method02("lesson20210629.Student");
        method03("lesson20210629.Student");
    }
    }

1.5、运行结果

2.反射访问方法

2.1、要被访问自定义方法的类声明如下

package lesson20210629;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Student {


    /**
     * 自定义方法
     */
    public void showMsg(){//无参无返回方法
        System.out.println("无参无返回方法");
    }

    public void setName(String name){//有参无返回方法
        System.out.println("有参,值为:"+name);
    }

    public String getName(){//无参有返回方法
        System.out.println("带返回值的方法");
        return "qn";
    }

    private void youName(){//私有无参无返回方法
        System.out.println("私有你的名字");
    }


    //特殊参数
    public void setBirthday(Date birthday){
        System.out.println("你的生日:"+new SimpleDateFormat("yyyy-mm-dd").format(birthday));
    }

    //参数是数组
    public void addStuName(String []names){
        int i = 0;
        for (String name:names) {
            System.out.println(name+(i++==names.length-1?"":","));
        }
    }
}

2.2无参构造方法访问不同参数有无返回值方法

//无参构造方法访问无参无返回值方法
    public static void method01(String addr){
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getMethod("showMsg",null);//参数为空可写可不写
            m.invoke(s);//调用方法
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //无参构造方法访问有参无返回值方法
    public static void method02(String addr){
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getMethod("setName",String.class);//参数为空可写可不写
            m.invoke(s,"qn");//调用方法
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //无参构造方法访问无参有返回值方法
    public static void method03(String addr) {
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getMethod("getName");//参数为空可写可不写
            String name = (String) m.invoke(s);//调用方法
            System.out.println("有返回值:" + name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //无参构造方法访问私有化无参无返回值方法
    public static void method04(String addr) {
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getDeclaredMethod("youName");//参数为空可写可不写
            m.setAccessible(true);//暴力
           m.invoke(s);//方法的调用
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void method05(String addr){
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getMethod("setBirthday", Date.class);//参数为空可写可不写
            m.invoke(s,new Date());//调用方法
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void method06(String addr){
        try {
            Class clazz = Class.forName(addr);
            //通过无参构造方法创建对象
            Student s = (Student) clazz.newInstance();
            Method m = clazz.getMethod("addStuName", String[].class);//参数为空可写可不写
//            m.setAccessible(true);
            m.invoke(s,(Object)new String[]{"123","1234","12345"});//调用方法
        }catch (Exception e){
            e.printStackTrace();
        }
    }

2.3、main方法

public class Test02 {
    public static void main(String[] args) {
        method01("lesson20210629.Student");
        method02("lesson20210629.Student");
        method03("lesson20210629.Student");
        method04("lesson20210629.Student");
        method05("lesson20210629.Student");
        method06("lesson20210629.Student");
    }
}

2.4运行结果

3、反射访问属性

3.1、要被访问自定义属性的类声明如下

package lesson20210629;

import java.text.SimpleDateFormat;
import java.util.Date;

public class Student {

    private String name;
    public int age;
    public static double height;
    private Date birthday;
}

3.1、访问属性的方式

package lesson20210629;

import java.lang.reflect.Field;

//反射属性
public class Test03 {

    public static void main(String[] args) throws Exception {
        method01("lesson20210629.Student");
        method02("lesson20210629.Student");

    }

    //公有化属性
    public static void method01(String addr) throws Exception{
        Class clazz = Class.forName(addr);
        Student s = (Student) clazz.newInstance();
        //获取属性
        Field f = clazz.getField("age");
        //set赋值
        f.set(s,23);
//        s.age = 23;//也可以
        //get输出
        int age = (int) f.get(s);
//        age = s.age;//也可以
        System.out.println(age);
    }

    //私有化属性
    public static void method02(String addr) throws Exception{
        Class clazz = Class.forName(addr);
        Student s = (Student) clazz.newInstance();
        //获取属性
        Field f = clazz.getDeclaredField("name");
        f.setAccessible(true);//暴力
        //set赋值
        f.set(s,"qn");
//        s.age = 23;//也可以
        //get输出
        String name = (String)f.get(s);
//        age = s.age;//也可以
        System.out.println(name);
    }
}

3.2、运行结果


总结

反射机制作用:一般用于做框架的,把抽象的底层代码反射到日常的开发中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值