反射

反射

在运行状态中,对于任意一个类,都能够知道这个类的所有的属性方法;
优点:
可以解耦,提高程序的可扩展性。
可以在运行过程中,操作(获取,设置)这些对象。
动态语言:
是一类程序在运行过程中可以改变语言结构的语言。
获取class对象:
1.forName(),将字节码文件加载到内存,返回与带有给定字符串得类或接口相关联的class对象,在源代码阶段,静态获取class对象。
2.类名.class:通过类名属性.class对象获取:class对象阶段
3.对象getclass()返回运行时class类
注意:
同一个字节码文件在加载时只会被加载一次,不会创建多个class对象。
都是同一个对象,加载完类之后就会在堆内存中产生一个clsaa类型的数据,(一个类只有一个对象)。

package com.rongyu.day13;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反射
 */
public class Dome02 {
    public static void main(String[] args) throws Exception {
        getMethod();
    }
    //获取属性
    public static void getFiled() throws Exception {
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        //获取属性
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            //获取属性的包装类
            Class<?> type = declaredField.getType();
            String simpleName = type.getSimpleName();
            //获取属性名字
            String name = declaredField.getName();
            //获取属性的修饰符
            int modifiers = declaredField.getModifiers();
            String s = Modifier.toString(modifiers);
            //打印
            System.out.println(s+simpleName+name);
        }
    }
    //获取类中的构造方法
    public static void getConstructor() throws Exception{
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        //获取类中所有的构造方法
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            //获取修饰符
            String s = Modifier.toString(constructor.getModifiers());
            //获取方法名
            String name = constructor.getName();
            //获取参数
            Class<?>[] parameterTypes = constructor.getParameterTypes();
            String str = "";
            for (Class<?> parameterType : parameterTypes) {
                str += parameterType.getSimpleName()+",";
            }
            System.out.println(s+name+"("+str+")"+"{}");
        }
    }
    //获取类中的方法
    public static void getMethod() throws Exception{
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            //获取修饰符
            String s = Modifier.toString(declaredMethod.getModifiers());
            //获取返回值
            String simpleName = declaredMethod.getReturnType().getSimpleName();
            //获取方法名
            String name = declaredMethod.getName();
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            String str = "";
            for (Class<?> parameterType : parameterTypes) {
                str += parameterType.getSimpleName()+" ";
            }
            System.out.println(s+simpleName+name+"("+str+")"+"{}");
        }
    }

}

在这里插入图片描述

package com.rongyu.day13;

import java.lang.reflect.Field;

/**
 * 使用反射访问私有的属性,方法
 */
public class Dome03 {
    public static void main (String[] args) throws Exception {
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        //实例化class对象
        Student o = (Student)aClass.newInstance();
        Field name = aClass.getDeclaredField("name");
        //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
        name.setAccessible(true);
        //obj - 应该修改其字段的对象
        //value - 正被修改的 obj 的字段的新值
        name.set(o,"ZhangSan");
        System.out.println(o);
    }
}

在这里插入图片描述

package com.rongyu.day13;

import java.lang.reflect.Array;

/**
 * 对数组的反射
 */
public class Dome04 {
    public static void main(String[] args) {
        Object o = Array.newInstance(String.class, 4);
        Array.set(o,0,"1");
        Array.set(o,1,"2");
        Array.set(o,2,"3");
        Array.set(o,3,"4");
        for (int i = 0; i < Array.getLength(o); i++) {
            Object o2 = Array.get(o, i);
            System.out.println(o2);
        }

    }
}

在这里插入图片描述

  //反射只有在程序运行的过程中才能会进行赋值
    public static void setMethod() throws Exception{
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        //进行实例化对象
        Student student = (Student) aClass.newInstance();
        Method setName = aClass.getMethod("setName", String.class);
        setName.invoke(student, "ZhangSan");
        System.out.println(student);
    }

在这里插入图片描述

package com.rongyu.day13;

import java.lang.reflect.Array;

/**
 * 通过反射改变数组的大小
 */
public class Dome05 {
    public static void main(String[] args) {
        Integer[] arr = {1,2,3,4,5};
        //使用反射创建一个新的数组
        Object o = Array.newInstance(Integer.class, 10);
        //获取原先数组的长度
        int length = Array.getLength(arr);
        //复制数组
        System.arraycopy(arr,0,o,0,length);
        //获取数组对象
        Class<?> aClass = o.getClass();
        //判断该类是不是一个数组
        if (!aClass.isArray()){
            return;
        }
        //循环输出数组
        for (int i = 0; i < Array.getLength(o); i++) {
            Object o1 = Array.get(o, i);
            if (o1==null){
                break;
            }
            System.out.println(o1);
        }
    }
}

在这里插入图片描述

 //有参的构造方法
    public static void getConstructor() throws Exception {
        //获取字节码的class对象
        Class<?> aClass = Class.forName("com.rongyu.day13.Student");
        //得到有参数的构造方法
        Constructor<?> constructor = aClass.getConstructor(String.class, Integer.class);
        Student zhangSan = (Student)constructor.newInstance("ZhangSan",123);
        System.out.println(zhangSan);
    }

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值