反射理解

news/2024/5/19 3:31:07 标签: 反射

1.Class这个类用于操作一个类的属性,方法,构造器。
2.类的共同点:都有方法,属性,构造器。抽取出来就是Class类
3.方法的共同点:都有返回值,参数。抽取出来就是Method类
4.属性的共同点:都有类型,都有name。抽取出来就是Field类
在写代码当中,基本就是围绕着 Class类,Constructor类,Method类—invoke(obj,args[])方法,Field类来完成。
直接上代码了,看到的朋友可以拷贝到本地运行实践下,自己在此贴出也是方便自己以后复习:
一个Person类

package reflect;

public class Person {

    private String name;
    private String age;
    private String address;
    public String getName() {
        return name;
    }
    public Person(String name, String age, String address) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public static void main(String[] args) {
        String[] aa = new String[]{"1","2"};
        System.out.println(aa.length);
        for(String a : aa){
            System.out.println(a);
        }
    }
    @Override
    public String toString() {
        return "Person [address=" + address + ", age=" + age + ", name=" + name
                + "]";
    }

    public static void printInfo(){
        System.out.println("静态方法是反射调用");
    }
    private static void printInfo1(){
        System.out.println("静态方法1是反射调用");
    }
}

一个测试类,单元测试,方法比较多,自己已经标示清楚:

package reflect;

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

import org.junit.Test;

public class TestRef {

    /**
     * 获取Class对象
     * @throws ClassNotFoundException
     */
    @Test
    public void 测试1_通过forname获取类对象() throws ClassNotFoundException{
        Class<?> forName = Class.forName("java.lang.String");

        Method[] declaredMethods = forName.getDeclaredMethods();//所有方法
        //System.out.println(Arrays.toString(declaredMethods));
        for(Method m :declaredMethods){
            System.out.println(m);
        }
        System.out.println("--------------------");
        Field[] declaredFields = forName.getDeclaredFields();//所有属性
        for(Field f : declaredFields){
            System.out.println(f);
        }
        System.out.println("------------------------");
        Constructor<?>[] constructors = forName.getConstructors();//所有构造器
        for(Constructor<?> c : constructors){
            System.out.println(c);
        }
    }

    public void test2(Object obj){
        Class<?> forName = obj.getClass();
        System.out.println("---------方法-----------");
        Method[] declaredMethods = forName.getDeclaredMethods();//所有方法
        //System.out.println(Arrays.toString(declaredMethods));
        for(Method m :declaredMethods){
            System.out.println(m);
        }
        System.out.println("---------属性-----------");
        Field[] declaredFields = forName.getDeclaredFields();//所有属性
        for(Field f : declaredFields){
            System.out.println(f);
        }
        System.out.println("---------构造器---------------");
        Constructor<?>[] constructors = forName.getConstructors();//所有构造器
        for(Constructor<?> c : constructors){
            System.out.println(c);
        }
    }
    public void test4(){
        Class<?> forName = Person.class;
        System.out.println("---------方法-----------");
        Method[] declaredMethods = forName.getDeclaredMethods();//所有方法
        //System.out.println(Arrays.toString(declaredMethods));
        for(Method m :declaredMethods){
            System.out.println(m);
        }
        System.out.println("---------属性-----------");
        Field[] declaredFields = forName.getDeclaredFields();//所有属性
        for(Field f : declaredFields){
            System.out.println(f);
        }
        System.out.println("---------构造器---------------");
        Constructor<?>[] constructors = forName.getConstructors();//所有构造器
        for(Constructor<?> c : constructors){
            System.out.println(c);
        }
    }

    @Test
    public void 测试2_通过getClass方法获取对象(){
        Person p = new Person();
        test2(p);
    }
    @Test
    public void 测试3_通过点class获取对象(){
        test4();
    }

    /**
     * 获取带有具体参数的属性,方法,构造器
     * @throws ClassNotFoundException
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws NoSuchMethodException
     */
    @Test
    public void 测试4() throws ClassNotFoundException, SecurityException, NoSuchFieldException, NoSuchMethodException{
        Class<?> forName = Class.forName("reflect.Person");

        //获得具体的属性
        Field declaredField = forName.getDeclaredField("age");
        System.out.println(declaredField);
        //获得具体的方法
        Method method = forName.getMethod("getName", new Class[]{});
        Method methodSet = forName.getMethod("setName", new Class[]{String.class});
        System.out.println(method);
        System.out.println(methodSet);
        //获得构造器
        Constructor<?> constructor = forName.getConstructor(new Class[]{});//无参构造
        Constructor<?> constructor1 = forName.getConstructor(new Class[]{String.class,String.class,String.class});//有参构造
        System.out.println(constructor);
        System.out.println(constructor1);
    }

    @Test
    public void 根据构造器获取对象实例() throws Exception{
        Class<?> forName = Class.forName("reflect.Person");
        Constructor<?> constructor1 = forName.getConstructor(new Class[]{});//无参构造
        Constructor<?> constructor2 = forName.getConstructor(new Class[]{String.class,String.class,String.class});//有参构造
        Object newInstance11 = constructor1.newInstance(new Object[]{});
        System.out.println("无参构造:"+newInstance11.toString());
        Object newInstance22 = constructor2.newInstance(new Object[]{"aa","bb","cc"});
        System.out.println("有参构造:"+newInstance22.toString());
    }

    @Test
    public void 反射_给set方法赋值() throws Exception{
        Class<?> forName = Class.forName("reflect.Person");
        //获得无参构造
        Constructor<?> constructor1 = forName.getConstructor(new Class[]{});
        //获取实例化对象
        Object newInstance = constructor1.newInstance(new Object[]{});
        //获取所有方法
        Method[] methods = forName.getDeclaredMethods();
        for(Method m : methods){
            System.out.println(m);
            String methodName = m.getName();
            if(methodName.startsWith("set")){
                String field = methodName.substring(3);
                //获取相对应的属性名字
                String real_field = field.substring(0, 1).toLowerCase()+field.substring(1);
                System.out.println(real_field);
                //获得方法所对应的属性
                Field field2 = forName.getDeclaredField(real_field);
                //获取属性对应的类型
                Class<?> type = field2.getType();
                if(type == Integer.class){
                    //反射调用set方法
                    m.invoke(newInstance, new Object[]{1});
                }
                if(type == String.class && real_field.equals("address")){
                    m.invoke(newInstance, new Object[]{"北京"});
                }
                if(type == String.class && real_field.equals("name")){
                    m.invoke(newInstance, new Object[]{"袁会亮"});
                }

            }
        }
        System.out.println(newInstance);

    }

    @Test
    public void 反射invoke方法赋值() throws Exception{
        Class<?> forName = Class.forName("reflect.Person");
        //获得无参构造
        Constructor<?> constructor1 = forName.getConstructor(new Class[]{});
        //获取实例化对象
        Object newInstance = constructor1.newInstance(new Object[]{});

        Method declaredMethod_set = forName.getDeclaredMethod("setName", new Class[]{String.class});
        Object invoke_set = declaredMethod_set.invoke(newInstance, new Object[]{"傻宝"});

        /*Person p = new Person();
        p.setName("傻宝1");*/


        Method declaredMethod_get = forName.getDeclaredMethod("getName", new Class[]{});
        Object invoke_get = declaredMethod_get.invoke(newInstance, new Object[]{});
        System.out.println(invoke_get);


        Method declaredMethod_static = forName.getDeclaredMethod("printInfo", null);
        declaredMethod_static.invoke(null, null);//静态的 直接调用

    }

    @Test
    public void 反射获取属性赋值() throws Exception{
        Class<?> forName = Class.forName("reflect.Person");
        //获得无参构造
        Constructor<?> constructor1 = forName.getConstructor(new Class[]{});
        //获取实例化对象
        Object newInstance = constructor1.newInstance(new Object[]{});
        //根据属性名字获取属性对象
        Field declaredField = forName.getDeclaredField("name");
        //破坏掉私有属性
        declaredField.setAccessible(true);
        declaredField.set(newInstance, "傻宝");

        Method declaredMethod_static = forName.getDeclaredMethod("printInfo1", null);
        declaredMethod_static.setAccessible(true);
        declaredMethod_static.invoke(null, null);//静态的 直接调用
        System.out.println(newInstance);
    } 

    @Test
    public void 通过反射拷贝对象() throws Exception{
        Person p = new Person();
        p.setAddress("洛阳");
        p.setAge("11");
        p.setName("xing");
        Object copyObject = copyObject(p);
        System.out.println("得到的对象:"+copyObject.toString());
    }

    public static Object copyObject(Object obj) throws Exception{

        Class<? extends Object> class1 = obj.getClass();
        //获取构造器
        Constructor<? extends Object> constructor = class1.getConstructor(new Class[]{});   
        //获取新的实例
        Object newInstance = constructor.newInstance(new Object[]{});

        //获取传递的对象属性
        Field[] fields = class1.getDeclaredFields();
        for(Field f : fields){
            //获取属性名字
            String name = f.getName();
            //获取属性的类型
            Class<?> type = f.getType();
            //获取set方法名字
            String set_method = "set"+name.substring(0, 1).toUpperCase()+name.substring(1);
            //获取get方法名字
            String get_method = "get"+name.substring(0, 1).toUpperCase()+name.substring(1);
            //获取get方法
            Method gMethod = class1.getDeclaredMethod(get_method, new Class[]{});
            Object gResult = gMethod.invoke(obj, new Object[]{});
            //获取set方法
            Method sMethod = class1.getDeclaredMethod(set_method, type);
            //给新的实例赋值
            sMethod.invoke(newInstance, gResult);
        }
        return newInstance;
    }
}

http://www.niftyadmin.cn/n/1368469.html

相关文章

自定义注解-Annotation

最近连着把这一系列的相关知识看完了&#xff0c;最后再总结一下自定义注解&#xff0c;想到年初在一家公司面试的时候&#xff0c;还被问到这些知识&#xff0c;还好现在自己把它补充上来了&#xff0c;废话不多说&#xff0c;自己记录一下学习自定义注解过程中感觉重要的知识…

证实同步函数使用的是this锁

**提前先注意这个提醒&#xff1a;&#xff1a; 1.同步函数分为静态和非静态的&#xff0c;下边演示的是非静态的方式&#xff0c;准确来说应该是非静态同步函数采用的是this**锁&#xff0c;静态函数采用的是当前类的字节码文件&#xff0c;也就是&#xff08;类.class&#…

死锁案例分析

死锁的产生以及解决办法&#xff0c;看代码分析&#xff0c;注意里边的注释&#xff0c;自行运行。 package thread;/*** 模拟买票* * author yhl* */class Thread02 implements Runnable{private static int countTraket 100;public boolean flag true;private Object mut…

多线程有三大特性和Java内存模型

三大特性: 原子性、可见性、有序性 什么是原子性 即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断&#xff0c;要么就都不执行。 一个很经典的例子就是银行账户转账问题&#xff1a; 比如从账户A向账户B转1000元&#xff0c;那么必然包括2个操作&#…

volatile与synchronized区别

仅靠volatile不能保证线程的安全性。&#xff08;原子性&#xff09; 1.volatile轻量级&#xff0c;只能修饰变量。synchronized重量级&#xff0c;还可修饰方法 2.volatile防止重排序。 要理解这个问题&#xff0c;先要了解对象的构造过程&#xff0c;实例化一个对象其实可…

synchronized—生产者与消费者线程实例分析

先看几个概念&#xff0c;实例里边主要是通过wait和notify来实现的。 wait()、notify()、notifyAll()是三个定义在Object类里的方法&#xff0c;可以用来控制线程的状态。 这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。 如果对象调用了…

锁的两个基本工具—synchronized和Lock

1.ReentrantLock 与synchronized有相同的并发性和内存语义&#xff0c;还包含了中断锁等候和定时锁等候&#xff0c;意味着线程A如果先获得了对象obj的锁&#xff0c;那么线程B可以在等待指定时间内依然无法获取锁&#xff0c;那么就会自动放弃该锁。2.但是由于synchronized是在…

LinK3D论文详解

摘要 特征提取和匹配是许多计算机视觉任务的基本部分&#xff0c;例如二维或三维物体检测、识别和配准。众所周知&#xff0c;二维特征提取和匹配已经取得了很大的成功。遗憾的是&#xff0c;在3D领域&#xff0c;由于描述能力差和效率低&#xff0c;目前的方法无法支持3D激光雷…