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语言的反射机制。

相关推荐
玖玥拾13 分钟前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾32 分钟前
Rust 学习目录
开发语言·学习·rust
我命由我123451 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑1 小时前
Sentinel安装
java·后端·微服务
云泽8081 小时前
从零吃透 C++ 异常:抛出捕获、栈展开、异常重抛与编码规范详解
开发语言·c++·代码规范
灯澜忆梦1 小时前
GO---可见性规则
开发语言·golang
逝水无殇1 小时前
C# 文件的输入与输出详解
开发语言·数据库·后端·c#
这是个栗子2 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
凤凰院凶涛QAQ2 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
研☆香3 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript