反射——反射API,使用反射创建数组
反射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,使用反射创建数组的更多相关文章
- Java 反射 Array动态创建数组
Java 反射 Array动态创建数组 @author ixenos 注:java.lang.reflect.Array 是个反射工具包,全是静态方法,创建数组以多维数组为基准,一维数组只是特殊实现 ...
- 反射入门-浅谈反射用途_根据Ado游标对象创建list集合
本人大二菜鸟一只,今天在上课期间有个同学看着C#反射的内容说反射没什么用,一时之间也想不到什么更好的例子,就写了个根据泛型类型和游标反射创建List集合的Demo. 首先创建一个用于封装对应数据的en ...
- [C#反射]C#中的反射解析及使用.
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 参考: C#反射,MSDN编程指南 反射是一个程序集发现及运行的过程,通过 ...
- .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)——转载
原文链接:https://blog.walterlv.com/post/dotnet-high-performance-reflection-suggestions.html ***** 大家都说反射 ...
- C#工具:反射帮助类 泛型反射帮助类
反射帮助类 using System; using System.Reflection; using System.Data; using System.Drawing; using System.R ...
- [Java反射基础四]通过反射了解集合泛型的本质
本文接上文"方法反射的基本操作",利用反射了解下java集合中泛型的本质 1.初始化两个集合,一个使用泛型,一个不使用 ArrayList list1 = new ArrayLis ...
- ABP示例程序-使用AngularJs,ASP.NET MVC,Web API和EntityFramework创建N层的单页面Web应用
本片文章翻译自ABP在CodeProject上的一个简单示例程序,网站上的程序是用ABP之前的版本创建的,模板创建界面及工程文档有所改变,本文基于最新的模板创建.通过这个简单的示例可以对ABP有个更深 ...
- android 创建数组
一: private String[] data = new String[]{"Hello", "jike", "world"}; 二: ...
- C语言: 创建数组的几种方法
创建数组有三种方法 1.声明一个数组,声明时用常量表达式指定数组维数,然后可以用数组名访问数组元素 2.声明一个变长数组,声明时用变量表达式指定数组的维数,C99支持 3.声明一个指针,调用mallo ...
随机推荐
- 【转】MySQL数据丢失讨论
原文http://blog.sae.sina.com.cn/archives/4091 1. 概述 很多企业选择 MySQL都会担心它的数据丢失问题,从而选择Oracle,但是其实并不十分清楚什么 ...
- onethink入门笔记(二)
5.onethink页面端获得后台服务器传值的方法 1:一般后台通过assign的值前台通过{$value}显示出来; 2:如果需要在js中使用 则可以通过 在js中写 var m = "{ ...
- 新手上路,配置阿里云CentOS服务器LAMP
最近出了个9.9包月的阿里云一直想弄就买了个半年的,脑子一热选了个CentOS系统的然后就是无尽的代码...... 话不多说直接上步骤: 在实例中选择"连接管理终端",输入一些应 ...
- 英语学习app分析
以下数据分析由队员张波收集整理队员链接 队友的博客 一.数据统计 为了让统计数据更加准确可信,我们选取了三款android平台的应用市场软件作为数据的来源. 英语学习app下载量统计表: 序号 应用名 ...
- Spark Streaming架构设计和运行机制总结
本期内容 : Spark Streaming中的架构设计和运行机制 Spark Streaming深度思考 Spark Streaming的本质就是在RDD基础之上加上Time ,由Time不断的运行 ...
- 从request获取远程IP地址
public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-F ...
- 转:10年程序员谈.Net程序员的职业规划
从事Dotnet程序开发工作近10年了,从开始的月薪3k的小程序员菜鸟,到现在年薪60w的项目总经理,从战战兢兢的去各个公司应聘,到现在开始面试那些战战兢兢的小程序员,回想起这近十年来的经验,看着还是 ...
- 使用ab进行压力测试
在Windows系统的命令行下,进入ab.exe程序所在目录,执行ab.exe程序.注意直接双击无法正确运行.
- Hibernate框架简单应用
Hibernate框架简单应用 Hibernate的核心组件在基于MVC设计模式的JAVA WEB应用中,Hibernate可以作为模型层/数据访问层.它通过配置文件(hibernate.proper ...
- 29. Xshell连接Linux下Oracle无法回退的解决办法
使用Xshell 连接远程Linux 数据库服务器,当切换到sqlplus 控制台时,输入错误字符的时候,使用回退键修改时,显示^H. 解决方法:切换至root用户,直接输入stty erase ^H ...