反射API

Java.lang.Reflect库

①   Class类与Java.lang.Reflect类库一起对反射的概念进行支持。

②   java.lang包下:

a)         Class<T>:表示对一个正在运行的Java应用程序中的类和接口,是Reflection的起源。

③   java.lang.reflect包下:

a)         Field类:代表类的成员变量(成员变量也称类的属性)。

b)         Method类:代表类的方法。

c)         Constructor类:代表类的构造方法。

d)         Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

通过反射实例化对象

① 常情况下我们通过new Object来生成一个类的实例,但有时我们没法直接new,只能通过反射动态生成。

② 实例化无参构造函数的对象,两种方式:

a)         Class.newlnstance();

b)         Class.getConstructor(new Class[]{}).newInstance(new Object[]{})

③ 实化带参构造函数的对象

a)         clazz.getConstructor(Class<?>… parameterTypes).newInstance(Object… initargs)

通过反射获取并调用方法

① 得当前类以及超类的public Method(共有方法)

a)         Method[] arrMethod=classType.getMethods();

② 得当前类申明的所有Method

a)         Method[] arrMethod=classType.getDeclaredMethods();

③ 获得当前类以及超类指定的public Method

a)         Method method=classType.getMethod(String name,Class<?>… parameterTypes);

④ 得当前类申明的指定的Method

a)         Method method=classType. getDeclaredMethods (String name,Class<?>… parameterTypes);

⑤ 通过反射动态运行指定Method

a)         Object obj=method.invoke(Object obj,Object… args);

通过反射获取并调用属性

① 得当前类以及超类的public Field

a)Field[] arrFields=classType.getField();

② 获得当前类申明的所有Field

a)Field[] arrFields=classType.getDeclaredFields();

③ 获得当前类以及超类指定的public Field

a)       Field field=classType.getField(String name);

④ 获得当前类申明的指定的Field

a)         Field field=classType.getDeclaredField(String name);

⑤ 通过反射动态设定Field的值

a)         field.set(Object obj,Object value);

⑥ 通过反射动态获取Field的值

a)         Object obj=field.get(Object obj);

----------------------------------------------------------------------------------------------------

代码

创建一个Employee类

 class Employee {
private String name;
private int age; public Employee() {
System.out.println("无参构造方法");
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
} @Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
} private void work() {
System.out.println("working...");
} }

在主方法中获取类的属性及方法:

         // 获取Employee这个类所关联的class对象
Class<?> classType = Class.forName("com.iotek.reflection.Employee");
// 通过反射机制来构造一个Employee的实例对象(默认调用无参数的构造方法)
Employee employee = (Employee) classType.newInstance();
System.out.println(employee);

输出结果:

无参构造方法

Employee [name=null, age=0]

         // 调用指定的构造方法来构造对象(无参构造方法)
Constructor<?> constructor = classType.getConstructor(new Class[] {});
Employee employee2 = (Employee)constructor.newInstance(new Object[] {});
System.out.println(employee2);

输出结果:

无参构造方法

Employee [name=null, age=0]

         // 调用指定的构造方法来构造对象(带参构造方法)
Constructor<?> constructor2 = classType.getConstructor(new Class[] {String.class, int.class });
Employee employee3 = (Employee) constructor2.newInstance(new Object[] {"zhangsan", 20 });
System.out.println(employee3);

输出结果:

Employee [name=zhangsan, age=20]

         // 获取Class对象所指定的所有方法,包括私有的
Method[] methods = classType.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName() + "--" + method.getModifiers()
+ "--" + method.getReturnType());
}

输出结果:

toString--1--class java.lang.String

getName--1--class java.lang.String

setName--1--void

work--2--void

getAge--1--int

setAge--1—void

         // 获取Class对象所指定的方法,包括私有的
Method method2 = classType
.getDeclaredMethod("toString", new Class[] {});
System.out.println(method2);
// 方法的调用
String desc = (String) method2.invoke(employee3, new Object[] {});
System.out.println(desc);

输出结果:

public java.lang.String com.iotek.reflection.Employee.toString()

Employee [name=zhangsan, age=20]

         // 调用私有方法
Method method3 = classType.getDeclaredMethod("work", new Class[] {});
System.out.println(method3.getName());
method3.setAccessible(true);// 设置私有方法可以访问
// 方法的调用
method3.invoke(employee3, new Object[] {});

输出结果:

work

working...

         // 获取Class对象所指定的属性,包括私有的
Field field = classType.getDeclaredField("name");
field.setAccessible(true);
field.set(employee3, "李四");
System.out.println(field.get(employee3));

输出结果:

李四

使用反射来创建一维数组:

         // 创建一个一维数组(String)
Class<?> classType = Class.forName("java.lang.String");
Object array = Array.newInstance(classType, 5);
Array.set(array, 3, "abc");
System.out.println(Array.get(array, 3));

输出结果:

abc

使用反射来创建二维数组:

         // 创建一个二维数组(3行3列)
int[] dimens = { 3, 3 };
Object array2 = Array.newInstance(int.class, dimens);
Object arrayObj = Array.get(array2, 2);// 获取第三行(就是一个一维数组)
Array.setInt(arrayObj, 2, 10);// 给指定数组位置的元素赋值
int [][] arr = (int [][]) array2;
System.out.println(arr[2][2]);

输出结果:

10

反射总结

①   只要用到反射,先获得Class对象。

②   没有方法能获得当前类的超类的private方法和属性,你必须通过getSuperclass()找到超类以后再去尝试获得。

③   通常情况下即使是当前类,private属性或方法也是不能访问的,你需要设置压制权限setAccessible(true)来取得private的访问权。但是,这已经破坏了面向对象的规则,所以除非万不得已,请尽量少用。

反射——反射API,使用反射创建数组的更多相关文章

  1. Java 反射 Array动态创建数组

    Java 反射 Array动态创建数组 @author ixenos 注:java.lang.reflect.Array 是个反射工具包,全是静态方法,创建数组以多维数组为基准,一维数组只是特殊实现 ...

  2. 反射入门-浅谈反射用途_根据Ado游标对象创建list集合

    本人大二菜鸟一只,今天在上课期间有个同学看着C#反射的内容说反射没什么用,一时之间也想不到什么更好的例子,就写了个根据泛型类型和游标反射创建List集合的Demo. 首先创建一个用于封装对应数据的en ...

  3. [C#反射]C#中的反射解析及使用.

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 参考: C#反射,MSDN编程指南 反射是一个程序集发现及运行的过程,通过 ...

  4. .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)——转载

    原文链接:https://blog.walterlv.com/post/dotnet-high-performance-reflection-suggestions.html ***** 大家都说反射 ...

  5. C#工具:反射帮助类 泛型反射帮助类

    反射帮助类 using System; using System.Reflection; using System.Data; using System.Drawing; using System.R ...

  6. [Java反射基础四]通过反射了解集合泛型的本质

    本文接上文"方法反射的基本操作",利用反射了解下java集合中泛型的本质 1.初始化两个集合,一个使用泛型,一个不使用 ArrayList list1 = new ArrayLis ...

  7. ABP示例程序-使用AngularJs,ASP.NET MVC,Web API和EntityFramework创建N层的单页面Web应用

    本片文章翻译自ABP在CodeProject上的一个简单示例程序,网站上的程序是用ABP之前的版本创建的,模板创建界面及工程文档有所改变,本文基于最新的模板创建.通过这个简单的示例可以对ABP有个更深 ...

  8. android 创建数组

    一: private String[] data = new String[]{"Hello", "jike", "world"}; 二: ...

  9. C语言: 创建数组的几种方法

    创建数组有三种方法 1.声明一个数组,声明时用常量表达式指定数组维数,然后可以用数组名访问数组元素 2.声明一个变长数组,声明时用变量表达式指定数组的维数,C99支持 3.声明一个指针,调用mallo ...

随机推荐

  1. web页面设计基本原则

    1.对齐. 不对齐看起来糟糕极了.简直一片混乱,会给人一种很不专业的印象.对齐让页面更漂亮一些,更重要的是便于更好的传达信息. 2.去掉糟糕的边框.边框会产生一种分离感. 3.亲密性. 元素相互靠近看 ...

  2. Linux下的文件与目录操作 BY 四喜三顺

      文件操作权限: chmod 三个八进制数字 文件名 其中:三个八进制数字,第一个代表本用户的权限,第二个代表同组的权限,第三个代表其他用户的权限4代表可读2代表可写1代表可执行例如:chmod 7 ...

  3. jquery ajax 返回值 中文时乱码或变成问号解决方法

    转载自jquery的 ajax返回值为中文时乱码解决方法 用jquery的ajax,遇到个问题,服务器端从数据库取到的数据没有出现中文乱码问题(日志打出来是没有乱码的),但是异步传到客户的时候却出现了 ...

  4. Python之MySQL操作及Paramiko模块操作

    一.MySQL简介   MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQ ...

  5. 解决json日期格式问题的3种方法

    这篇文章主要介绍了解决json日期格式问题的3种方法 ,需要的朋友可以参考下 开发中有时候需要从服务器端返回json格式的数据,在后台代码中如果有DateTime类型的数据使用系统自带的工具类序列化后 ...

  6. Spring整合log4j

    log4j2.xml放在类加载路径下,类加载路径就是WEB-INF文件夹下的classses文件,因为运行时,src包里的java类会被编译成.class盘文件,放在WEB-INF文件夹下的class ...

  7. jenkins:通过execute shell启动的进程会被杀死的问题

    [问题]在jenkins中配置自动更新部署项目时,如果采取用execute shell启动/关闭tomcat,会发现可以进行关闭tomcat,但是无法启动tomcat,虽然构建会显示执行成功,但是查看 ...

  8. Windows内核原理系列01 - 基本概念

    1.Windows API Windows 应用编程接口(API)是针对WIndwos操作系统用户模式的系统编程接口,包含在WindwosSDK中. 2.关于.NET .NET由一个被称为FCL的类库 ...

  9. Caffe应用篇----文件格式转换

    网友文章: 我们手中有的一般都是图片数据,jpg.bmp格式等,但caffe常使用的数据是db格式(leveldb/lmdb),因此首先我们要将自己数据转换成caffe可运行的格式文件.别捉鸡,caf ...

  10. GetStoredProcCommand和GetSqlStringCommand的区别

    原文:http://www.ithao123.cn/content-4004602.html http://hi.baidu.com/847270942/blog/item/c224dd557ff74 ...