JAVA反射

概念:

在运行状态中在仅知道一个类名时,就可以动态获得类中信息,创建对象,调用对象成员机制,称为java反射机制

在学习框架之前使用java类的方法

● 已知一个类的类名、以及、类中的方法属性、构造方法等

● 使用new关键字创建对象

● 使用对象调用方法或属性

Java反射的作用

• 动态获取类的信息。

如何获得类的class对象

1.通过Class类的静态方法forName
java 复制代码
   String classname ="com.wph.javaReflect.User";
      

        Class clazz1 = Class.forName(classname);
        System.out.println(clazz1);
2.通过运行时类的属性
java 复制代码
   String classname ="com.wph.javaReflect.User";
       

        //方式2:
        Class clazz2=User.class;
       
3.调用getClass()
java 复制代码
    String classname ="com.wph.javaReflect.User";
   
        User user=new User();
        Class clazz3= user.getClass();

如何获得获得Constructor类(构造方法)

1.Constructor getConstructor(Class... parameterTypes) :

通过指定参数类型,返回构造方法实例。

2.Constructor类可以通过getXXX方法获得构造方法的基本信息.

3.getName:返回构造方法的名字

4.除了获得构造方法的基本信息,还可以创建实例 newInstance(Object... initargs) :创建实例

java 复制代码
  String classname="com.wph.javaReflect.User";

        //1.通过类名获得类的class对象
        Class aClass=Class.forName(classname);

        //2.通过类的CLass对象,创建对象
        Object object=aClass.newInstance();
        System.out.println(object);

        //获得类中的构造方法,通过构造方法api中的方法创建对象
        Constructor constructor=aClass.getConstructor();//获得指定的公共构造方法
        Object object1=constructor.newInstance();//创建对象

        Constructor constructor1=aClass.getConstructor(String.class,String.class);
        Object object2=constructor1.newInstance("zhangsan","1111");

        Constructor [] constructors=aClass.getConstructors();//获得所有公共的构造方法
        System.out.println(constructors.length);

       /* aClass.getDeclaredConstructor();//获得类中任意构造方法,包含私有
        aClass.getDeclaredAnnotations();//获得类中所有构造方法*/

如何获得获得Field(成员变量)

1.public Field getField(String name)通过指定Field名字,返回 Field实例.

2.Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也 可以对属性进行赋值.

java 复制代码
 String classname="com.wph.javaReflect.User";

        //1.通过类名获得类的class对象
        Class aClass=Class.forName(classname);

        Object object=aClass.newInstance();

       // Field accountField = aClass.getField("account");//获得指定名称的公共成员变量
/*
        Field accountField= aClass.getDeclaredField("account");//获得指定名称的成员变量,包含私有的
          accountField.setAccessible(true);
          accountField.set(object, "admin");
        System.out.println(object);*/

        HashMap<String,String> map=new HashMap<String, String>();
                       map.put("account", "admin");
                       map.put("Password", "1111");

                       Field[] declaredFields = aClass.getDeclaredFields();
                       for(Field field:declaredFields){
                           field.setAccessible(true);
                           field.set(object,map.get(field.getName()));
                       }
        System.out.println(object);
    }

如何获得获得Method(类中的方法)

1.Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例

2.getName:获得方法名字

  1. getParameterTypes:获得方法参数类型 ●

4.除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法 ●

5.invoke(Object obj, Object... args) :使用obj调用该方法,参数为args

java 复制代码
  String classname="com.wph.javaReflect.User";

        //1.通过类名获得类的class对象
        Class aClass=Class.forName(classname);

        Object object=aClass.newInstance();
        HashMap<String,String> map=new HashMap<String, String>();
        map.put("account", "admin");
        map.put("password", "1111");

        //先拿到类中所有的私有属性
        Field[] declaredFields = aClass.getDeclaredFields();
        for(Field field : declaredFields){
            //根据属性名 生成set方法名称
            String setmethod= "set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
            //通过Class对象,获得对应的set方法对象
            Method setmethodObj = aClass.getMethod(setmethod, field.getType());
            //调用set方法
            setmethodObj.invoke(object,map.get(field.getName()));

        }
        System.out.println(object);
    }

反射案例

自定义java对象转json工具类

java 复制代码
package com.wph.javaReflect;

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

public class jsonutil {
    public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clazz=object.getClass();
        String json="{";
        Field[] declaredFields =clazz.getDeclaredFields();
        for(Field field : declaredFields) {
            //生成属性get方法名字
            String getmethod = "get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
            //获得方法对象
            Method method=clazz.getMethod(getmethod );
            //调用方法
            Object value=method.invoke(object);
            //把属性名和值拼接成键值
            json+=field.getName()+":"+value+",";

        }
        json=json.substring(0,json.length()-1);//去掉多余逗号
        json+="}";
        return json;
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        User user=new User();
        user.setAccount("admin");
        user.setPassword("1111");

        Car car=new Car();
        car.setName("bm");
        car.setColor("red");
        System.out.println(jsonutil.objectToJson(user));
        System.out.println(jsonutil.objectToJson(car));
    }
}

反射优缺点

● 优点:

1.增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作

2.提高代码的复用率,比如动态代理

3.可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态 调用

缺点:

1.反射会涉及到动态类型的解析,导致性能要比非反射调用更低

2.使用反射技术通常要在一个没有安全限制的程序运行.

3.反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象 性

总结

AVA反射机制是在运行状态中,对于任意一个类,都能够知道这个 类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个 方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 java语言的反射机制。

相关推荐
XiaoLeisj2 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck2 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei2 小时前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师3 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉3 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer3 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq4 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml44 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~4 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616884 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端