java中的反射

1、java中的反射:

首先要理解什么是Class类,反射就是通过获取Class对象之后的一系列操作。

1、对于每个类而言,JRE 都为其保留一个不变的 .Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。
2、Class 对象只能由系统建立对象。每个类的实例都会记得自己是由哪个 Class 实例所生成。
3、一个类在 JVM 中只会有一个Class实例。
 

2、获取Class对象的三种方式:

package com.example.demo.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.util.Arrays;

public class ReflectionTest2 {

    static class Test {
    }

    static class Person {
        public String name;
        private int age;

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


    /**
     * 实例化Class类的方式有点特殊,有三种方式: 对象.getClass( )、  类.Class 、   Class.forName(“包名下的类”)
     *
     * Class<?> class 方法
     *
     * 反射调用
     */
    public static void main(String[] args) throws Exception {

        //方式一:
        Test test = new Test();
        Class<?> c1 = test.getClass();
        System.out.println(c1);

        //方式二:
        //为了避免特殊性,这里不用Test类,而用java库中的String类
        Class<String> c2 = String.class;
        System.out.println(c2);

        //方式三:
        //forName()方法会抛出异常
        Class<?> c3 = null;
        try {
            c3 = Class.forName("com.example.demo.test.ReflectionTest2");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(c3);

//====================Class对象里面的属性===============================================
        Class<?> c = null;
        try {
            c = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Constructor<?>[] cons = c.getConstructors();
        System.out.println("取得类的构造方法:" + Arrays.toString(cons));

        Class<?>[] in = c.getInterfaces();
        System.out.println("取得类所实现的接口:" + Arrays.toString(in));

        Class<?> su = c.getSuperclass();
        System.out.println("取得父类:" + su);

        Method[] methods = c.getMethods();
        for (int i = 0; i < methods.length; i++) {
            //System.out.println("取得类的全部方法:" + methods[i]);
        }

        Field[] f = c.getDeclaredFields();
        for (int i = 0; i < f.length; i++) {
            System.out.println("取得本类的全部属性:" + f[i]);
        }

//=========================重设反射对象的值==========================================
        Person p = new Person("zhangsan",12);
        Class<?> aClass = p.getClass();

        //获取公共属性的值
        Field f1 = aClass.getField("name");
        //get(p)表明要获取是哪个对象的值
        String str = (String) f1.get(p);
        System.out.println("姓名:" + str);

        //获取私有属性的值
        Field f2 = aClass.getDeclaredField("age");
        //age是私有属性,所以要设置安全检查为true
        f2.setAccessible(true);
        int age = (int) f2.get(p);
        System.out.println("年龄:" + age);
    }



}
 

3、反射方法使用:

package com.example.demo.test;

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

/**
 * @Author Tim
 * @Date 2021/2/4 11:29
 */

class Person {
    private String name;

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

    public String toString() {
        return "姓名: " + this.name;
    }

    public void print(int i) {
        System.out.println("我在写字: " + i);
    }

    public static void say(String str) {
        System.out.println("我在说话: " + str);
    }
}

public class ReflectionTest3 {

//===================通过反射修改对象属性================================================

    public static void main(String[] args) throws Exception {
        Person p = new Person("王二狗");
        System.out.println("反射前对象===" + p);
        Class<?> c = p.getClass();

        //定义要修改的属性
        Field f = c.getDeclaredField("name");
        f.setAccessible(true);
        //修改属性,传入要设置的对象和值
        f.set(p, "张二蛋");
        System.out.println("通过反射修改属性===" + p);


//====================通过反射调用对象方法===============================================

        //getMethod()方法需要传入方法名,和参数类型
        Method m1 = c.getMethod("print", int.class);
        //invoke()表示调用的意思,需要传入对象和参数
        m1.invoke(p, 10);

        Method m2 = c.getMethod("say", String.class);
        //这里的null表示不由对象调用,也就是静态方法
        m2.invoke(null, "你妹");
    }


}

 测试demo1:

package com.example.demo.test;

import java.lang.reflect.Method;

class FunClass {

    public String sayHello(String s) {
        return "hello!" + s;
    }
}

public class Test {

    public static void main(String[] args) throws Exception {

        Class<?> clz = Class.forName("com.example.demo.test.FunClass");
        //
        Object obj = clz.newInstance();
        //获取方法
        Method m = obj.getClass().getMethod("sayHello", String.class);
        //调用方法
        String result = (String)m.invoke(obj, "参数,李");
        System.out.println(result);
    }
}
posted @ 2021-02-04 14:32  威兰达  阅读(229)  评论(0编辑  收藏  举报