罪恶克星 发表于 2024-9-4 02:25:20

java框架底子--反射

前言

        本文将详细报告反射的基本概念以及反射底层代码的部门实现
反射

        就是步调在运行状态时,对于任何一个类,都在仅知道类名的状态下,动态获取该类中的全部属性和方法(包括私有),可以动态地通过该类的对象调用类的属性和方法的机制称为反射机制
        是将java中的类映射成一个个对象
        比方类中拥有成员变量,成员方法,构造方法等等信息,而反射机制就是将这些信息映射成一个个对象.而在这个过程中干系的类主要包括
Class 范例         Constructor 构造方法          Method 方法          Field 属性
        除了Class外,其他类都位于java.lang.reflect包中
         可见,反射API将类的范例、方法、属性都封装成了类,此中最重要的类是 Class,可以说,反射的使用都是从Class开始.
Class类

        Class类是Java反射机制的底子,通过Class类,可以得到一个类的基本信息
        一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被 使用时都会创建一个Class对象。
        那么就有一个题目:
怎样得到Class对象

        Class类的对象,表示当前正在运行中的类和接口.
        以一个User类和一个Car类举例:
此中User类的成员变量有account,password
Car类中的成员变量有name,color
        使用反射机制时,我们只知道类的名称(包名+类名)
   String classname = "com.zhu.javareflect.User";
        方式一:Class类的静态方法 forName(String name)
   Class clazz1 = Class.forName(classname);
        System.out.println(clazz1);
        方式二:类名.class方式:适用于通过类名得到Class实例的环境
    Class clazz2 = User.class;
        System.out.println(clazz1==clazz2);
         方式三:Object类中的getClass方法:适用于通过对象得到Class实例的环境
   User user = new User();
            Car car = new Car();
        Class clazz3 =  user.getClass();
        Class clazz4 = car.getClass();
         System.out.println(clazz1==clazz3);

API中 Constructor 构造方法

除Class类之外,我们还可以通过API中 Constructor 构造方法得到类中的构造方法来得到类中的信息
Class类中界说了如下方法 
Constructor getConstructor(Class... parameterTypes) :
通过指定参数范例,返回构造方法实例。

得到类中的构造方法,通过构造方法api中的方法创建对象

Constructor实例通过Class实例得到,所以都须要Class对象
   String classname = "com.zhu.javareflect.User";
1.通过类名,得到类的Class对象
     Class aClass = Class.forName(classname);
        System.out.println(aClass);
2.通过类的Class对象,创建对象
   Object object = aClass.newInstance();
        System.out.println(object);
3.得到类中的构造方法,通过构造方法api中的方法创建对象
        Constructor类可以通过getXXX方法得到构造方法的基本信息
        getName:返回构造方法的名字 
         除了得到构造方法的基本信息,还可以创建实例
        newInstance(Object... initargs) :创建实例
   Constructor constructor1 = aClass.getConstructor();//得到指定的公共构造方法
                 Object object1 =  constructor1.newInstance();
            Constructor constructor2 = aClass.getConstructor(String.class,String.class);
                 Object object2 =  constructor2.newInstance("zhangsan","111");
        System.out.println(object1);
        System.out.println(object2);
        Constructor [] constructors = aClass.getConstructors();//得到全部公共的构造方法
        System.out.println(constructors.length);
4。虽然可以得到私有构造方法,但是一样平常不建议操纵私有成员,会突破封装性
    aClass.getDeclaredConstructor();//得到类中任意的构造方法,包含私有的
        aClass.getDeclaredConstructors();//得到类中全部的构造方法,包含私有的

Field 属性

相同的,我们也可以通过field属性来获取类中的信息
得到Field实例例,都是通过Class中的方法实现
public Field getField(String name)通过指定Field名字,返回 Field实例.
........ 注意Field的访问权限
Field类的作用
Field类将类的属性进行封装,可以得到属性的基本信息、属性的值,也 可以对属性进行赋值.
getName:返回属性的名字
set:设置属性值

得到类中成员变量

Field实例通过Class实例得到,所以都须要Class对象
   String classname = "com.zhu.javareflect.User";
1.通过类名,得到类的Class对象
     Class aClass = Class.forName(classname);
2.通过类的Class对象,创建对象
   Object object = aClass.newInstance();
3.得到类中成员变量
       Field accountField =  aClass.getField("account");//得到指定名称的公共的成员变量
    Field accountField =  aClass.getDeclaredField("account");//得到指定名称的公共的成员变量  包含私有的

         accountField.setAccessible(true);//允许访问操纵私有属性
         accountField.set(object, "admin");
         System.out.println(object);
4.以聚集的情势获取类中信息
        模仿从数据库查到的数据
    HashMap<String,String> map = new HashMap<>();
                      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 方法

Method实例都是通过Class类的方法得到
Method getMethod(String name, Class... parameterTypes) :
通过指定方法名,参数范例,返回一个Method实例
Method类的作用
Method类将类中的方法进行封装,可以动态得到方法的信息,比方
getName:得到方法名字
getParameterTypes:得到方法参数范例
除了动态得到方法信息外,Method还能动态调用某一个对象的详细方法
invoke(Object obj, Object... args) :使用obj调用该方法,参数为args

演示通过属性的get和set方法,对类中私有属性进行赋值取值操纵

Method实例通过Class实例得到,所以都须要Class对象

   String classname = "com.zhu.javareflect.User";
1.通过类名,得到类的Class对象
     Class aClass = Class.forName(classname);
2.通过类的Class对象,创建对象
   Object object = aClass.newInstance();
 3.模仿从数据库查到的数据
   HashMap<String,String> map = new HashMap<>();
map.put("account", "admin");//account,password是根据类名中的属性名进行更改
map.put("password", "1111");

4.把查询到的数据封装到对象中
先拿到类中的全部的私有属性
   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工具类 

JsonUtil是类名
在main方法中对User类和Car类中的属性存入数据
   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("宝马");
    car.setColor("红色");
    System.out.println(JsonUtil.objectToJson(user));
    System.out.println(JsonUtil.objectToJson(car));
}
 在main方法外界说objectToJson(Object object)方法
   public static String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //得到传入参数object的Class对象
    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);
            //调用方法
            String value = (String) method.invoke(object);
            //把属性名和值拼接成键值
            json +=field.getName()+":"+value+",";
        }
        json = json.substring(0,json.length()-1);//去掉多余的逗号
        json +="}";
    return json;
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: java框架底子--反射