Java_反射

反射概念

关于反射,我的理解就是在任意一个类中我们都能获取它的对象,对于任意一个对象,我们都可以调用它的方法和属性;这种动态获取信息并能够调用其方法的称之为反射

class类在Java的API详解

在class类中每个类都包含了属性、构造方法、属性方法,为了拿到class类中的内容,我们就要用思到了反射来获取需求类的对象,并通过这个对象调用方法和属性。

代码详解:


/**
 * 反射:加载类,获取类的字节码、
 *             构造器对象constructor、
 *             成员变量field、
 *             成员方法method
 */
public class reflect {
    private String name;
    private int age;

    public reflect() {
        System.out.println("无参构造器执行...");
    }

    public reflect(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("有参构造器执行...");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "reflect01{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    void method(String name){
        System.out.println(name+"说:method方法运行中...");
    }
}

实现定义一个reflect类,并设置相应的属性、方法

 /** 获取类 */
    void GetClass() throws Exception {

        Class c1 = reflect.class;
        System.out.println(c1);
        System.out.println(c1.getName());


        Class c2 = Class.forName("Java01.反射.reflect");
        System.out.println(c2.getName());


        reflect ref=new reflect();
        Class c3 = ref.getClass();
        System.out.println(c3.getName());


        //c1、c2、c3相等
        System.out.println("c1、c2、c3是否相等: "+(c1 == c2 && c2 == c3));

    }

在一个新类中获取student类对象的三种方法

通过这三种方式获得的类都相同

​/**获取所有构造器 */
    void GetGonstructor()throws Exception{

        Class cl= reflect.class;

        //1.获取所有公有的构造器--public
        Constructor[] constructors1 = cl.getConstructors();
        for (Constructor constructor : constructors1) {
            //          构造器名称     +   构造器参数数量
            System.out.println(constructor.getName()
                    +"--->"+constructor.getParameterCount());
        }

        System.out.println("------------------------");
        //2.获取所有声明的构造器
        Constructor[] constructors2 = cl.getDeclaredConstructors();

        for (Constructor constructor : constructors2) {
            System.out.println(constructor.getName()
                    +"--->"+constructor.getParameterCount());
        }

        System.out.println("------------------------");

    }

通过对象调用其构造方法,一个类中可能有多个构造函数,所以要用构造器数组来接收方法

 /**获取指定构造器 */
    void GetGonstructor2()throws Exception{
        Class c= reflect.class;
        //获取无参构造器
        Constructor constructor = c.getDeclaredConstructor();

        System.out.println(constructor.getName()
                +"-->"+constructor.getParameterCount());

        constructor.setAccessible(true);//禁止检查访问权限
        reflect r1=(reflect) constructor.newInstance();//获取类对象
        System.out.println(r1);

        //获取有参的构造器
        Constructor constructor3 = c.getDeclaredConstructor(String.class,int.class);

        System.out.println(constructor3.getName()
                +"--->"+constructor3.getParameterCount());

        constructor3.setAccessible(true);
        reflect r2=(reflect) constructor3.newInstance("贼贼贼",15);//对构造器进行赋值
//        reflect r2=(reflect) constructor3.newInstance();//或者不用赋值
        System.out.println(r2);
    }

获取指定构造器的方法


 

/**获取成员变量 */
    void GetField() throws Exception {
        Class c1 = reflect.class;

        //获取所有成员变量
        Field[] Fields = c1.getDeclaredFields();
        for (Field field : Fields) {
            System.out.println(field.getType()+"---"+field.getName());
        }

        //获取指定成员变量
        Field fName=c1.getDeclaredField("name");
        System.out.println(fName.getType()+"---"+fName.getName());

        Field fAge=c1.getDeclaredField("age");
        System.out.println(fAge.getType()+"---"+fAge.getName());


        //为成员变量赋值
        reflect ref=new reflect();
        fName.setAccessible(true);
        fName.set(ref,"zzz");
        System.out.println(ref);

        //取值
        String name = (String) fName.get(ref);
        System.out.println(name);

    }

可以获取成员变量的类型和值

还可以获取属性类,并进行赋值

公有变量和私有变量都能赋值!!!

/**获取成员方法 */
    void GetMethod() throws Exception{
        System.out.println("获取成员方法:");
        System.out.println();
        Class ref= reflect.class;

        //获取全部成员方法
        Method[] declaredMethods = ref.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("-----------------");
        //获取指定成员方法
        Method m1 = ref.getDeclaredMethod("getName");//无参不加参数
        System.out.println(m1.getName());

        Method m2 = ref.getDeclaredMethod("method", String.class);//有参不加参数
        System.out.println(m2.getName());

        reflect rr=new reflect();
        m1.setAccessible(true);
        String inMethod = (String) m1.invoke(rr);//调用方法执行
        System.out.println(inMethod);

        m2.setAccessible(true);
        String inMethod2 = (String) m2.invoke(rr,"哈哈哈");
        System.out.println(inMethod2);


    }

通过对象获取去它的成员变量

反射的优点:

反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类

反射的缺点:
因为是JVM操作,所以对于性能来说会有所下降。
容易对程序源码造成一定的混乱。

反射的使用场合:
在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值