Java深入分析讲解反射机制

目录
  • 反射的概述
  • 获取Class对象的三种方式
  • 通过反射机制获取类的属性
  • 通过反射机制访问Java对象的属性
  • 反射机制与属性配置文件的配合使用
    • 资源绑定器
    • 配合使用样例
  • 通过反射机制获取类中方法
  • 通过反射机制调用Java对象的方法
  • 通过反射机制获取类中的构造方法
  • 通过反射机制创建对象(调用构造方法)
  • 通过反射机制获取一个类的父类和父接口

反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

获取Class对象的三种方式

第一种方式:

通过调用java.lang.Class类下的静态方法:static Class forName(String className)

注意:

  • 参数是一个带有包名的完整类名(同目录下的可以只写类名)。
  • 抛出编译时异常:ClassNotFountException
  • 该方法会导致相应的类被类加载。

代码如下:

public class MyClass {
    static{
        System.out.println("静态代码块执行!");
    }
}
class Test{
	Class c = Class.forName("MyClass");
}

编译结果:

第二种方式:

Object类下有个方法: public final Class getClass() ----- 返回此对象的Class。

代码如下:

Date d = new Date();
Class c2 = d.getClass();

第三种方式:

Java种任何一种类型,包括基本数据类型,都有class静态属性,直接通过 类名.class,就可以返回相应的Class类。

代码如下:

Class c = Date.class;

通过反射机制获取类的属性

相关方法:

public Field[] getFields() ------- java.lang.Class中的方法,将类中public修饰的属性以数组的形式返回

public Field[] getDeclaredFields() ------ java.lang.Class中的方法,将类中所有的属性以数组的形式返回

public Class getType() ------ java.lang.reflect.Field中的方法,获取属性的类型并返回

public int getModifiers() ----- java.lang.reflect.Field中的方法,获取属性的修饰符,并以整数编码的形式返回(一个整数编码可能代表多个修饰符)

static String toString(int mod) ------ java.lang.reflect.Modifier中的静态方法,传入修饰符的整数编码,以字符串的形式将修饰符返回

代码如下:

public class ReflectTest05 {
    public static void main(String[] args) throws Exception{
        Class c = Class.forName("java.lang.String");
        StringBuffer s = new StringBuffer();
        s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "{\n");
        Field[] fields = c.getDeclaredFields();
        for(Field f:fields){
            s.append("\t" + Modifier.toString(f.getModifiers()) + " "+ f.getType().getName()+ " " +f.getName()+"\n");
        }
        s.append("}");
        System.out.println(s);
    }
}

编译结果如下:

通过反射机制访问Java对象的属性

创建一个User类,如下:

public class User {
    //四个Field对象,分别采用四种不同的访问权限修饰符
    public int no;
    private String name;
    protected  int age;
    boolean sex;
}

代码如下:

public class ReflectTest06 {
    public static void main(String[] args) throws Exception{
        Class c = Class.forName("User");
        //通过反射实例化User类
        Object user = c.newInstance();
        //设置User对象的no
        Field field = c.getDeclaredField("no");
        field.set(user,12);
        //获得User对象的no
        System.out.println(field.get(user));
        //设置User对象的name,需要打破封装,因为name属性是私有属性,不能直接设置
        Field field1 = c.getDeclaredField("name");
        field1.setAccessible(true);
        field1.set(user,"Joke");
        System.out.println(field1.get(user));
    }
}

反射机制与属性配置文件的配合使用

资源绑定器

java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。

使用以下这种方式的时候,属性配置文件xxx.properties必须放到类路径下。

代码如下:

public class ResourceBundleTest01 {
    public static void main(String[] args) {
        //资源绑定器,只能绑定xxx.properties文件,并且这个文件必须在类路径下,文件扩展名也必须是properties
        //并且在写路径时,路径后面的扩展名不能写
        ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
        String className = bundle.getString("className");
        System.out.println(className);
    }
}

配合使用样例

首先我们创建一个属性配置文件,如下:

className = User
fieldName = name
fieldValue = zhangsan

样例代码如下:

public class ReflectTest07 {
    public static void main(String[] args) throws Exception{
        //配合属性文件使用
        ResourceBundle bundle = ResourceBundle.getBundle("classinfo");
        Class c2 = Class.forName(bundle.getString("className"));
        //通过反射实例化User类
        Object obj = c2.newInstance();
        Field field1 = c2.getDeclaredField(bundle.getString("fieldName"));
        //打破封装
        field1.setAccessible(true);
        field1.set(obj,bundle.getString("fieldValue"));
        System.out.println(field1.get(obj));
    }
}

通过反射机制获取类中方法

代码如下:

public class ReflectTest08 {
    public static void main(String[] args)throws Exception {
        Class c = Class.forName("java.lang.String");
        Method[] methods = c.getDeclaredMethods();
        StringBuffer s = new StringBuffer();
        for(Method m:methods){
            Class[] parameterTypes = m.getParameterTypes();
            s.append(Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getSimpleName() + " " + m.getName() + "(");
            for(Class cs:parameterTypes){
                s.append(cs.getSimpleName() + " ");
            }
            s.append("){}\n");
        }
        System.out.println(s);
    }
}

编译结果:

通过反射机制调用Java对象的方法

使用反射机制调用一个对象的方法,步骤如下:

  • 获取对应类的Class对象。
  • 通过反射机制实例化出一个对象。
  • 通过方法 :public Method getDeclaredMethod(String name, Class... parameterTypes),获取对应的Method对象

注意:getDeclaredMethod方法是在java.lang.Class下的方法,第一个参数是方法名,第二个参数是可变长参数,是该方法的形式参数类型列表

  • 通过方法:public Object invoke(Object obj,Object... args),可以调用Method对象对应的方法。

注意:该方法是java.lang.reflect.Method下的方法,第一个参数是对象,第二个参数是方法的实际参数列表。

往User类中添加方法,如下:

public class User {
    //四个Field对象,分别采用四种不同的访问权限修饰符
    public int no;
    private String name;
    protected  int age;
    boolean sex;
    public int doSome(int i){
        System.out.println("User对象中的doSome方法执行!");
        return i;
    }
}

代码如下:

public class ReflectTest09 {
    public static void main(String[] args)throws Exception {
        Class c = Class.forName("User");
        Object obj = c.newInstance();
        Method method = c.getDeclaredMethod("doSome",int.class);
        System.out.println(method.invoke(obj,1));
    }
}

编译结果如下:

通过反射机制获取类中的构造方法

public class ReflectTest10 {
    public static void main(String[] args)throws Exception {
        Class c = Class.forName("java.lang.String");
        Constructor[] constructors = c.getDeclaredConstructors();
        StringBuffer s = new StringBuffer();
        for(Constructor co: constructors){
            s.append(Modifier.toString(co.getModifiers()) + " " +c.getSimpleName() + "(");
            Class[] parameterType = co.getParameterTypes();
            for(Class cs:parameterType){
                s.append(cs.getSimpleName()+" ");
            }
            s.append("){}\n");
        }
        System.out.println(s);
    }
}

编译结果如下:

通过反射机制创建对象(调用构造方法)

代码如下:

public class ReflectTest11 {
    public static void main(String[] args)throws Exception {
        Class c = Class.forName("User");
        //默认调用无参数构造方法
        Object obj1 = c.newInstance();
        //因为每一个构造方法的方法名都一样,所以getDeclaredConstructor方法的参数只有要调用的构造方法的构造参数类型列表
        Constructor constructor = c.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
        Object obj2 = constructor.newInstance(1111,"zhangsan",18,true);
        System.out.println(obj2);
    }
}

通过反射机制获取一个类的父类和父接口

代码如下:

public class ReflectTest12 {
    public static void main(String[] args)throws Exception {
        Class c = Class.forName("java.lang.String");
        //一个类最多只有一个父类
        Class superClass = c.getSuperclass();
        System.out.println(superClass.getName());
        //一个类可以实现多个接口
        Class[] superInterfaces = c.getInterfaces();
        for(Class i: superInterfaces){
            System.out.println(i.getName());
        }
    }
}

编译结果如下:

到此这篇关于Java深入分析讲解反射机制的文章就介绍到这了,更多相关Java反射机制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java十分钟精通反射机制原理

    什么是反射? 反射机制是在运行状态中,它为Java提供一种"操作对象"的能力,在运行状态下,通过Class文件对象,可以调用到任何类里面的属性.方法.以及构造方法,包括私有的,所有的类在反射机制面前都是透明的 自己的概括:通过Class文件对象可以看到这个类里面的所有东西,并且可以使用和修改 反射的前提是获取Class文件对象((字节码对象),那么一共有三种方式获取: Class.forName("全类名") ----通过Class类的静态方法(最常用) 类名.cl

  • Java反射机制,如何将一个实体类所有字段赋值为null

    目录 将一个实体类所有字段赋值为null 起因 第一种方法 第二种方法 将实体类中的null属性置为““或者空值 工具类 测试类 先创建需要的实体 将一个实体类所有字段赋值为null 起因 在我们想要使用一个实体类的时候,如果发现创建这个类的时候,给某一些字段设置了初始值(某些场景下的特殊需要),但我们这个时候又不需要这些初始化值的时候,我们就会想要把这些值全部清除掉,让其变为一个干净的类,我们可以手动一个一个去赋null值,我一开始就是这么做的,同事看到后告诉我,你可以尝试使用反射机制,自己封

  • JAVA的反射机制你了解多少

    目录 1.什么是反射? 2.反射能够干什么? 3.反射相关API 4.Class类的理解 (1).介绍: (2).类的加载过程: ①加载: ②链接: ③初始化 ④使用 ⑤卸载 (3)类加载器 总结 1.什么是反射? 在java开发中有一个非常重要的概念就是java反射机制,也是java的重要特征之一. 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力,通过反射可以调用私有方法和私有属性,大部分框架也都是运用反射原理的. Reflectio

  • Java反射机制原理、Class获取方式以及应用场景详解

    目录 学习背景 一.Java反射机制是什么? 1.1 反射原理 1.2 反射例子 二.Java反射机制中获取Class的三种方式及区别? 2.1 Class的几种获取方式 2.2 代码演示几种方式的区别 三.Java反射机制的应用场景有哪些? 3.1 应用场景 3.2 简单工厂模式优化 3.2.1 什么是简单工厂模式? 3.2.2 简单工厂模式有什么用? 3.2.3 如何实现简单工程模式? 3.2.4 简单工厂模式优化 3.2.5 简单工厂模式再次优化 3.3 代理模式中的动态代理实现 3.3.

  • Java反射机制如何解决数据传值为空的问题

    目录 反射机制数据传值为空的问题 java反射处理空值 反射机制数据传值为空的问题 两个小方法,用于解决BeanUtils.copyProperties(x, y);中源对象的值为空问题 1.通过实体注解数据库字段为Map的Key,需要的非空值为Value封装数据 @Override     public Map<String, Object> setNodeParamItems(DispatchInfoItem dispatchInfoItem) throws NoSuchMethodExc

  • Java中的反射机制示例详解

    目录 反射 什么是Class类 获取Class实例的三种方式 通过反射创建类对象 通过反射获取类属性.方法.构造器 更改访问权限和实例赋值 运用场景 反射 反射就是把Java类中的各个成分映射成一个个的Java对象.即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法:对于任意一个对象,都能调用它的任意一个方法和属性.这种动态获取信息及动态调用对象方法的功能叫Java的反射机制 每一个Java程序执行必须通过编译.加载.链接和初始化四个阶段 1.编译:将.java.文件编译成字节码.

  • 图文详解java反射机制及常用应用场景

    目录 一.什么是java反射? 二.HelloWorld 三.类加载与反射关系 四.操作反射的java类 4.1.获取Class对象的三种方法 4.2.获取Class类对象的基本信息 4.3.获得Class对象的成员变量 4.4.获取Class对象的方法 4.5.方法的调用 4.6.创建类的对象(实例化对象) 五.反射的常用场景 5.1.通过配置信息调用类的方法 5.2.结合注解实现特殊功能 5.3.按需加载jar包或class 六.反射的优缺点 一.什么是java反射? 在java的面向对象编

  • Java实例讲解反射机制是怎么一回事

    Java反射机制的概述 1.Java的反射(reflection) :机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法.这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制.反射被视为动态语言的关键,反射让Java成为一个准动态语言 .缺点增加不安全性. 2.动态语言(弱类型语言) 是运行时才确定数据类型的语言,变量在使用之前无需申明类型,通常变量的值是被赋值的那个值的类型..

  • Java的反射机制一起来看看

    目录 一.什么是反射机制? 获得Class类对象的三种方式: 二.Class类 三.Package类 四.Field类 五.Method类 六.Constructor类 总结 一.什么是反射机制? 反射就是运行时识别类的能力,在运行时可以获得当前对象的类结构,动态创建类的实例,调用对象的方法等: 获得Class类对象的三种方式: 方式一 :Class.forName(“类名”); Class类的一个静态方法forName 加载类获得类对象 运行的类库中没有Person类,程序依然可以编译. Cl

  • Java深入分析讲解反射机制

    目录 反射的概述 获取Class对象的三种方式 通过反射机制获取类的属性 通过反射机制访问Java对象的属性 反射机制与属性配置文件的配合使用 资源绑定器 配合使用样例 通过反射机制获取类中方法 通过反射机制调用Java对象的方法 通过反射机制获取类中的构造方法 通过反射机制创建对象(调用构造方法) 通过反射机制获取一个类的父类和父接口 反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的

  • 一文搞懂Java中的反射机制

    前一段时间一直忙,所以没什么时间写博客,拖了这么久,也该更新更新了.最近看到各种知识付费的推出,感觉是好事,也是坏事,好事是对知识沉淀的认可与推动,坏事是感觉很多人忙于把自己的知识变现,相对的在沉淀上做的实际还不够,我对此暂时还没有什么想法,总觉得,慢慢来,会更快一点,自己掌握好节奏就好. 好了,言归正传. 反射机制是Java中的一个很强大的特性,可以在运行时获取类的信息,比如说类的父类,接口,全部方法名及参数,全部常量和变量,可以说类在反射面前已经衣不遮体了(咳咳,这是正规车).先举一个小栗子

  • Java中的反射机制详解

    Java中的反射机制详解 反射,当时经常听他们说,自己也看过一些资料,也可能在设计模式中使用过,但是感觉对它没有一个较深入的了解,这次重新学习了一下,感觉还行吧! 一,先看一下反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 反射是Java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接.但是反射使用不当会成本很高! 看概念很晕的,继续往下

  • Java如何基于反射机制获取不同的类

    什么是反射机制 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法.这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制.反射被视为动态语言的关键(在运行阶段可以改变其结构) 特点: 1.极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力 2.通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类 3.能够在运

  • 详解Java中的反射机制和动态代理

    一.反射概述 反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制.通俗点讲,通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以,这是一种动态获取类的信息以及动态调用对象方法的能力. 想要使用反射机制,就必须要先获取到该类

  • Java中的反射机制基本运用详解

    目录 Java中的反射机制基本运用 1.什么是反射(reflect) 2.反射机制提供的功能 3.反射->获取类对象 4.反射->利用无参构造实例化对象 5.反射->利用有参构造实例化对象 6.反射->调用无参方法 7.反射->调用有参方法 8.反射->访问私有方法 9.反射->类加载路径 总结 Java中的反射机制基本运用 看完反射可以了解一下注解 注解annotation://www.jb51.net/article/221276.htm 1.什么是反射(re

  • Java学习之反射机制及应用场景介绍

    前言: 最近公司正在进行业务组件化进程,其中的路由实现用到了Java的反射机制,既然用到了就想着好好学习总结一下,其实无论是之前的EventBus 2.x版本还是Retrofit.早期的View注解框架都或多或少的用到Java的反射机制. 什么是Java反射机制? JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的以及动态调用对象的方法的功能称为Java的反射机制. 反射机制提供了哪些功能? 在运行时判定

  • python通过实例讲解反射机制

    一.反射机制简介: 通过字符串的形式导入模块 通过字符串的形式,去模块中寻找指定的函数,并执行 规定用户输入格式 模块名/函数名 通过__import__的形式导入模块,并通过 hasattr和getattr 检查并获取函数返回值. 相关方法: getattr:--根据字符串的形式去某个模块中寻找东西 hasattr:--根据字符串的形式去某个模块中判断东西是否存在 setattr:--根据字符串的形式去某个模块中设置东西 delattr:--根据字符串的形式去某个模块中删除东西 二.反射机制初

随机推荐