博客
关于我
Java基础之反射
阅读量:249 次
发布时间:2019-02-28

本文共 4113 字,大约阅读时间需要 13 分钟。

反射

作为jdk1.5后的新特性,反射这个知识还是要掌握的,以前自己也知道个大概,但是从来没有系统的学习过,所以这次准备记录下。

先看看反射需要用到的包:java.lang.reflect

看看这个包的说明:

提供类和接口,以获得关于类和对象的反射信息。在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对其底层对等项进行操作。

在利用反射操作中,我们无非使用Constructor< T>、Field、Method三个类比较多。在我们学习这三个类之前,我们要知道java中通过字节码获取Class的三种方法:

  • 类名.class,例如,System.class

  • 对象.getClass(),例如,new Date().getClass()

  • Class.forName(“类名”),例如,Class.forName(“java.util.Date”)

下面我们通过实例测试:

(1)创建Person类

package com.dsw.reflect;public class Person {    private String name;    private String age;    public Person(){    }    public Person(String name,String age){        this.name = name;        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }    public void printMsg(){        System.out.println(this.name + "--" + this.age);    }}

 

(2)、编写测试类

 

public class ReflectDemo {/** * @param args */public static void main(String[] args) {    //通过类名.class获取字节码    Class clazz1 = Person.class;    //通过对象.getClass()获取字节码    Person person = new Person();    Class clazz2 = person.getClass();    //通过Class.forName("类名");获取字节码    try {        Class clazz3 = Class.forName("com.dsw.reflect.Person");        System.out.println("clazz1 == clazz2:" + (clazz1 == clazz2));        System.out.println("clazz2 == clazz3:" + (clazz2 == clazz3));        System.out.println("clazz1.equals(clazz2):" + clazz1.equals(clazz2));    } catch (ClassNotFoundException e) {        e.printStackTrace();    }}}

运行结果:

clazz1 == clazz2:trueclazz2 == clazz3:trueclazz1.equals(clazz2):true

只有获取到字节码,我们才能获取到类的Field、Method等相关方法。

 

Constructor

 

1、继承关系

const

2、方法集合 

constMethod

测试实例代码:

public static void main(String[] args) {    //通过类名.class获取字节码    Class
clazz = Person.class; //通过字节码获取构造函数 try { //获取具体的构造方法 Constructor
constructor = clazz.getConstructor(String.class,String.class); System.out.println(constructor.getName()); Person person = constructor.newInstance("张三","20岁"); person.printMsg(); //获取无参构造函数,无参构造函数只能创建无参的实例 Constructor
constructor1 = clazz.getConstructor(); System.out.println(constructor1.getName()); Person person1 = constructor1.newInstance(); person1.printMsg(); //获取所有的构造方法 Constructor
[] constructors = clazz.getConstructors(); for(int i=0;i
construct = constructors[i]; System.out.println(construct.getName()); } } catch (Exception e) { e.printStackTrace(); }}

运行结果:

com.dsw.reflect.Person张三--20岁2-java.lang.Stringcom.dsw.reflect.Personnull--nullcom.dsw.reflect.Personcom.dsw.reflect.Person

通过获取构造函数,我们可以创建对应的实例,然后使用类对象的方法。

 

Method

1、继承关系
method

 

2、方法集合

methodss
测试用例:
注意:
Method中invoke(Object obj,Object…args)第一个参数为类的实例,第二个参数为相应函数中的参数,我想问,我调用的函数本来是一个多参数(参数个数不确定)的函数,应该怎么办?

可以这样调用:method.invoke(object, new Object[][]{new Object[]{obj1, obj2}}); 

这样相当于object.method(obj1, obj2);

测试用例:

public static void main(String[] args) {    //通过类名.class获取字节码    Class
clazz = Person.class; try { Object obj = clazz.newInstance(); Method method = clazz.getMethod("printMethod", new Class[]{String.class}); method.invoke(obj, new Object[]{method.getName()}); //获取所有的公共声明的方法 Method[] methods = clazz.getMethods(); if(methods != null && methods.length >0){ for(int i=0;i

运行结果:

Method:printMethodgetNamesetNameprintMethodgetAgesetAgeprintMsgwaitwaitwaitequalstoStringhashCodegetClassnotifynotifyAll

 

Field

1、继承关系
field

 

2、方法集合

fiemthod
methodss
测试用例:

public static void main(String[] args) {    //通过类名.class获取字节码    Class
clazz = Person.class; try { //获取指定的字段名称 Field field = clazz.getDeclaredField("name"); System.out.println(field.getName()); /*获取所有的字段 * getFields获取的是公共的字段, * getDeclaredFields获取所有声明的字段 */ Field[] fields = clazz.getDeclaredFields(); if(fields != null && fields.length >0){ for(int i=0;i

运行结果:

namenameage
你可能感兴趣的文章
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032
查看>>
NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
查看>>
NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
查看>>
NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
查看>>
NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
查看>>
NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
查看>>
NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
查看>>
NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
查看>>
NIFI大数据进阶_使用NIFI表达式语言_来获取自定义属性中的数据_NIFI表达式使用体验---大数据之Nifi工作笔记0024
查看>>
NIFI大数据进阶_内嵌ZK模式集群1_搭建过程说明---大数据之Nifi工作笔记0015
查看>>
NIFI大数据进阶_内嵌ZK模式集群2_实际操作搭建NIFI内嵌模式集群---大数据之Nifi工作笔记0016
查看>>
NIFI大数据进阶_外部ZK模式集群1_实际操作搭建NIFI外部ZK模式集群---大数据之Nifi工作笔记0017
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_01---大数据之Nifi工作笔记0033
查看>>
NIFI大数据进阶_实时同步MySql的数据到Hive中去_可增量同步_实时监控MySql数据库变化_操作方法说明_02---大数据之Nifi工作笔记0034
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_01_实际操作---大数据之Nifi工作笔记0029
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
查看>>
NIFI大数据进阶_离线同步MySql数据到HDFS_说明操作步骤---大数据之Nifi工作笔记0028
查看>>
NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
查看>>
NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
查看>>