反射机制概述

1、反射机制概述

1.1、反射机制有什么用?

​ 通过Java语言中的反射机制可以操作字节码文件(class文件)。

1.2、反射机制相关的类在哪个包下?

​ 反射机制在java.lang.reflect.*包下。

1.3、反射机制相关的重要的类有哪些?

​ java.lang.class:代表整个字节码,代表一个类型。

​ java.lang.reflect.Method:代表字节码中的方法字节码。

​ java.lang.reflect.Constructor:代表字节码中的构造方法字节码。

​ java.lang.reflect.Field:代表字节码中的属性字节码。

2、获取Class的三种方式

/*
第一种:Class c =Class.forName("完整类带包名");
第二种:Class c = 对象.getClass();
第三种:java语言任何一种类型,包括基本数据类型,它都有.class属性。
*/
package com.wcs.reflect;

import java.util.Date;

/** 
 * 使用反射获取类的三种方式
 */
public class ReflectTest01 {
    public static void main(String[] args) {
        /*
        Class.forName()
        静态方法
        方法的参数是一个字符串
        字符串需要的是一个完整类名
        完整类名必须带有包名。java.lang包也不能省略。
         */
        Class c1 = null;
        try {
            c1 = Class.forName("java.lang.String");//代表String.class文件
            Class c2 = Class.forName("java.util.Date");//代表Date类型
            Class c3 = Class.forName("java.lang.Integer");//代表Integer类型
            Class c4 = Class.forName("java.lang.System");//代表System类型
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        //Java中任何一个对象都有一个方法:getClass()
        String s = "abc";
        Class x = s.getClass();//x代表String.class字节码文件,x代表String类型
        System.out.println(x == c1);//true (==判断的是对象的内存地址)

        //第三种方式
        Class z = String.class;
        Class k = Date.class;
        Class f = int.class;
        Class e = double.class;
        System.out.println(x == z);//true
    }
}

3、反编译Field

package com.wcs.field;

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

/**
 * 反编译
 * 获取类的属性
 */
public class ReflectTest03 {
    public static void main(String[] args) {
        try {
            //获取整个类
            Class studentClass = Class.forName("com.wcs.field.Student");

            //完整类名 com.wcs.field.Student
            String className = studentClass.getName();
            System.out.println(className);
            //简单类名 Student
            String simpleName = studentClass.getSimpleName();
            System.out.println(simpleName);
            //获取类中所有的public修饰的Field
            Field[] fields = studentClass.getFields();
            System.out.println(fields.length);//1
            //取出这个Filed
            Field f = fields[0];
            String fName = f.getName();
            System.out.println(fName);//no

            //获取所有的Filed
            Field[] fs = studentClass.getDeclaredFields();
            System.out.println(fs.length);//4
            //遍历fs
            for (Field field : fs) {
                System.out.println("=========");
                //获取属性的修饰符列表
                int i = field.getModifiers();
                System.out.println(i);//返回的是一个数字,每个数字是修饰符的代号
                //把数字转换成字符串
                String s = Modifier.toString(i);
                System.out.println(s);
                //获取属性的类型
                Class fType = field.getType();
                String typeName = fType.getName();
                System.out.println(typeName);
                //获取属性的名字
                System.out.println(field.getName());
            }

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

4、通过反射机制访问对象属性

package com.wcs.field;

import java.lang.reflect.Field;

/**
 * 怎么通过反射机制访问一个Java对象的属性?
 * 给属性赋值set
 * 获取属性值get
 */
public class ReflectTest04 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //不使用反射机制,怎么访问一个对象的属性?
        Student s = new Student();
        //给属性赋值
        s.no = 1111;
        //读取属性值
        System.out.println(s.no);

        //使用反射机制,怎么去访问一个对象的属性
        Class studentClass = Class.forName("com.wcs.field.Student");
        //obj就是一个Student对象,底层调用无参构造方法
        Object obj = studentClass.newInstance();
        //获取no属性
        Field noFiled = studentClass.getDeclaredField("no");
        //给no属性赋值2222
        noFiled.set(obj, 2222);
        /*
        反射机制虽然让代码变得复杂了,但是为了“灵活”,也是值得的。
         */
        //读取属性的值
        System.out.println(noFiled.get(obj));

        //可以访问私有的属性吗?
        Field nameField = studentClass.getDeclaredField("age");

        //打破封装(不安全)
        // nameField.setAccessible(true);//这样在外部也是可以访问的
        nameField.set(obj, 18);
        System.out.println(nameField.get(obj));//无法访问私有属性
    }
}

5、反编译Method

package com.wcs.method;

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

/**
 * 反射Method
 */
public class ReflectTest05 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取类
        Class studentClass = Class.forName("com.wcs.method.StudentSystem");

        //获取所有的Method (包括私有的)
        Method[] methods = studentClass.getDeclaredMethods();
        //遍历methods
        for (Method method : methods) {
            //获取修饰符列表
            System.out.println(Modifier.toString(method.getModifiers()));
            //获取返回值类型
            System.out.println(method.getReturnType());
            //获取方法名
            System.out.println(method.getName());
            //获取方法的参数类型列表
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println(parameterType.getSimpleName());
            }
        }

    }
}

6、反射机制调用方法

package com.wcs.method;

import java.lang.reflect.Method;

/**
 * 通过反射机制调用一个对象的方法
 */
public class ReflectTest06 {
    public static void main(String[] args) throws Exception {
        //不使用反射机制
        StudentSystem studentSystem = new StudentSystem();
        studentSystem.login("admin", "123");

        //使用反射机制来调用一个对象的方法
        Class stuClass = Class.forName("com.wcs.method.StudentSystem");
        //创建对象
        Object obj = stuClass.newInstance();
        //获取method
        Method loginMethod = stuClass.getDeclaredMethod("login", String.class, String.class);
        //调用方法
        System.out.println(loginMethod.invoke(obj, "admin", "123"));//true
    }
}

7、反射调用构造方法

package com.wcs.constructor;

import java.lang.reflect.Constructor;

/**
 * 通过反射调用构造方法
 */
public class ReflectTest07 {
    public static void main(String[] args) throws Exception {
        //不使用反射机制
        Vip v1 = new Vip();
        Vip v2 = new Vip(1001, "jack", true);
        System.out.println(v1);
        System.out.println(v2);

        //使用反射机制,调用无参构造方法
        Class vipClass = Class.forName("com.wcs.constructor.Vip");
        Object obj = vipClass.newInstance();

        //调用有参构造方法
        //获取有参构造方法
        Constructor con = vipClass.getDeclaredConstructor(int.class, String.class, boolean.class);
        //调用有参构造方法new对象
        Object newObj1 = con.newInstance(1002, "rose", false);
        System.out.println(newObj1);

        //获取无参构造方法
        Constructor con2 = vipClass.getDeclaredConstructor();
        //使用无参构造new对象
        Object newObj2 = con2.newInstance();
        System.out.println(newObj2);

    }
}

8、获取父类和父接口

package com.wcs.superIn;

/**
 * 通过反射获取父类和父接口
 */
public class ReflectTest08 {
    public static void main(String[] args) throws ClassNotFoundException {
        //String举例
        Class stringClass = Class.forName("java.lang.String");
        //获取String的父类
        Class superclass = stringClass.getSuperclass();
        System.out.println(superclass);
        //获取String类实现的所有接口
        Class[] interfaces = stringClass.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值