Java反射

一 Java 反射概述

          反射是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
Java反射机制提供的功能
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的成员变量和方法
生成动态代理

二 Java 反射实例

1.创建一个Person类。

package com.fengxunxinxi.reflection;

/**
 * Person calss
 * @author mofengyu
 *
 * @date 2019/10/26
 */

public class Person {

    private String name;
    private int age;

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    public void show(){
        System.out.println(".....");
    }

    public void display(String nation){
        System.out.println(nation);
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.运用反射创建Person类对象,执行操作

package com.fengxunxinxi.reflection;

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

/**
 * Test class
 * @author mofengyu
 *
 * @date 2019/10/26
 */

public class Test {

    public static void main(String[] args) throws Exception{
        Class clazz=Person.class;
        /**
         * 通过clazz的运行时类Person类创建对象
         */
        Person person=(Person)clazz.newInstance();
        System.out.println(person);
        /**
         * 获取name属性
         */
        Field field=clazz.getDeclaredField("name");
        field.setAccessible(true);
        field.set(person,"mofengyu");
        System.out.println(person);

        /**
         * 获取运行时类的方法
         */
        Method show=clazz.getMethod("show");
        /**
         * 执行方法
         */
        show.invoke(person);

        Method display=clazz.getMethod("display",String.class);
        /**
         * 执行Person类中的display方法
         */
        display.invoke(person,"CN");
    }
}

3.测试结果
在这里插入图片描述

三 Class类

          某个类的属性、方法和构造器、某个类实现了那些接口。对于类而言,JRE都为其保留一个不变的Class类型对象。一个Class类包含了特定类的有关信息。
1.Class本身也是一个类
2.Class对象只能由系统建立对象
3.一个类在JVM只会有一个Class实例
4.一个Class对象对应的是一个加载到JVM中的一个.classs文件
5.每个类实例都会记得自己是由那个Class实例生成的
6.通过Class可以完整地得到一个类中的完整结构
          java.lang.Class是反射的源头,创建一个类,通过编译(javac.exe),生成对应的.class文件。之后通过使用java.exe加载(JVM的类加载器加载此.class文件),此.class文件加载到内存后,就是一个运行时类,存在缓冲区,那么这个运行时类本身就是一个Class实例。
获取Class实例的四种方法

        /**
         * 获取Class实例的三种方法
         */

        /**
         * 调用运行时类的class属性
         */
        Class clazz1=Person.class;
        System.out.println(clazz1.getName());

        /**
         * 通过运行时类的对象获取
         */
        Person person=new Person();
        Class clazz2=person.getClass();
        System.out.println(clazz2.getName());
        /**
         * 通过Class的静态方法获取
         */
        String className="com.fengxunxinxi.reflection.Person";
        Class clazz3=Class.forName(className);
        System.out.println(clazz3.getName());

        /**
         * 通过类的加载器
         */
        ClassLoader classLoader=this.getClass().getClassLoader();
        Class clazz4=classLoader.loadClass(className);
        System.out.println(clazz4.getName());

四 ClassLoader

          类加载器是用来把类(Class)装载进内存的。JVM规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定义加载器(user-defined class loader)。JVM运行时会产生三个类加载器组成的初始化加载器层次。
          当程序主动使用这个类时,如果该类还未被加载到内存中,则系统会进行如下三个步骤来对该类进行初始化。
在这里插入图片描述

五 Class对象

1.创建类的对象:调用Class对象的newInstance()方法
1)类必须有一个无参数的构造器
2)类的构造器访问权限要足够

 package com.fengxunxinxi.reflection;

/**
 * TestConstroutor class
 * @author mofengyu
 *
 * @date 2019/10/31
 */

public class TestConstroutor {

    public static void main(String[] args) throws Exception{
        String className="com.fengxunxinxi.reflection.Person";
        Class clazz=Class.forName(className);
        Person person=(Person)clazz.newInstance();
        System.out.println(person);
    }
}

2.获取类的相关属性

package com.fengxunxinxi.reflection;

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

public class TestField {

    public static void main(String[] args) {
        Class clazz=Person.class;
        /**
         * getFields():只能获取到运行时类及父类中声明为pubilc的属性
         */
        Field[] fields=clazz.getFields();
        for(int i=0;i<fields.length;i++){
            System.out.println(fields[i]);
        }
        System.out.println();
        /**
         * 获取运行时类的所有属性
         */
        Field[] fields1=clazz.getDeclaredFields();
        for(Field field:fields1){
            /**
             * 获取权限修饰符
             */
            int s=field.getModifiers();
            String str= Modifier.toString(s);
            System.out.println(str);
            /**
             * 获取返回值
             */
            Class type=field.getType();
            System.out.println(type.getName());
            
            System.out.println(field);
        }
    }
}

3.获取方法

package com.fengxunxinxi.reflection;

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

/**
 * TestMethod class
 * @author mofengyu
 *
 * @date 2019/10/31
 */

public class TestMethod {

    public static void main(String[] args) {
        Class clazz=Person.class;
        /**
         * getMethods():获取运行时类及父类中声明为public的方法
         */
        Method[] methods=clazz.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }

        System.out.println();

        /**
         * getDeclaredMethods():获取运行时类本身声明的所有方法
         */
        Method[] methods1=clazz.getDeclaredMethods();
        for(Method m:methods1){
            /**
             * 获取注解
             */
            Annotation[] annotations=m.getAnnotations();
            for(Annotation annotation:annotations){
                System.out.println(annotation);
            }
            /**
             * 获取权限修饰符
             */
            String str=Modifier.toString(m.getModifiers());
            System.out.println(str);
            /**
             * 获取返回值类型
             */
            Class returnType=m.getReturnType();
            System.out.println(returnType.toString());
            /**
             * 获取方法名
             */
            System.out.println(m.getName());
            /**
             * 获取形参列表
             */
            Class[] params=m.getParameterTypes();
            for(Class param:params){
                System.out.println(param.getName());
            }
            /**
             * 获取异常
             */
            Class[] ex=m.getExceptionTypes();
            for(Class e:ex){
                System.out.println(e.getName());
            }
            System.out.println(m);
        }
    }
}

4.获取构造器

public static void main(String[] args) throws Exception{
        String className="com.fengxunxinxi.reflection.Person";
        Class clazz=Class.forName(className);
        Constructor[] constructors=clazz.getConstructors();
        for(Constructor constructor:constructors){
            System.out.println(constructor);
        }
    }

5.获取父类

public static void main(String[] args) {
        Class clazz=Person.class;
        /**
         * 获取运行时类的父类
         */
        Class superClass=clazz.getSuperclass();
        System.out.println(superClass);
        /**
         * 获取带泛型的父类
         */
        Type type=clazz.getGenericSuperclass();
        System.out.println(type);

        /**
         * 获取父类的泛型
         */
        ParameterizedType parameterizedType=(ParameterizedType)type;
        Type[] types=parameterizedType.getActualTypeArguments();
        System.out.println(((Class)types[0]).getName());
    }

6.获取其它相关信息

 public static void main(String[] args) {
        Class clazz=Person.class;
        /**
         * 获取实现的接口
         */
        Class[] interfaces=clazz.getInterfaces();
        for(Class in:interfaces){
            System.out.println(in.getName());
        }
        /**
         * 获取所在包
         */
        Package p=clazz.getPackage();
        System.out.println(p);
        /**
         * 获取注解
         */
        Annotation[] annotations=clazz.getAnnotations();
        for(Annotation annotation:annotations){
            System.out.println(annotation);
        }
    }

7.获取指定属性并赋值

public static void main(String[] args) throws Exception{
        Class clazz=Person.class;
        /**
         * 获取指定属性
         */
        Field name=clazz.getField("name");
        /**
         * 创建运行时对象
         */
        Person person=(Person)clazz.newInstance();
        System.out.println(person);
        /**
         * 运行时类指定属性赋值
         */
        name.set(person,"Jerry");
        System.out.println(person);

        Field age=clazz.getDeclaredField("age");
        age.setAccessible(true);
        age.set(person,18);
        System.out.println(person);
    }

7.获取指定方法并调用

 public static void main(String[] args) throws Exception{
          Class clazz=Person.class;
          /**
           * 获取指定方法,getMethod()获取声明为public的方法
           */
          Method show=clazz.getMethod("show");
          Person person=(Person)clazz.newInstance();
          Object returnValue=show.invoke(person);
          System.out.println(returnValue);
          /**
           * 获取toString()方法
           */
          Method toString=clazz.getMethod("toString");
          Object returnValue1=toString.invoke(person);
          System.out.println(returnValue1);

          Method info=clazz.getMethod("info");
          /**
           * 调用静态方法
           */
          Object returnValue2=info.invoke(Person.class);
          System.out.println(returnValue2);
          /**
           * 获取声明的方法
           */
          Method display=clazz.getDeclaredMethod("display",String.class,Integer.class);
          display.setAccessible(true);
          Object returnValue4=display.invoke(person,"CHN",1);
          System.out.println(returnValue4);
      }

8.调用指定构造函数

 public static void main(String[] args) throws Exception{
          String className="com.fengxunxinxi.reflection.Person";
          Class clazz=Class.forName(className);
          Constructor constructor=clazz.getDeclaredConstructor(String.class,int.class);
          constructor.setAccessible(true);
          Person person=(Person)constructor.newInstance("mmm",1);
          System.out.println(person);
      }
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值