——java中的反射
来源:互联网 发布:js 数组slice方法 编辑:程序博客网 时间:2024/06/05 22:34
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
什么是反射?
一,反射就是把java类中的各个成员,提取成其对应的java类对象。
例如:一个java类中用一个Class类的对象来表示,一个类中的组成部分都有对应的类:
Field —— 成员变量;
Method —— 成员方法;
Constructor —— 构造函数;
Package ——包
二,一个类中的每个成员可以用相对应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些
实例对象,就可以执行相应的操作了。
反射的基石 -- Class类
1,java中的各个java类属于同一类事物,描述这类事物的java类名就是Class。
注:对比:众多人用一个Person类表示,众多的java类就用Class表示
a,一个人 -->Person
b,java类 -->Class
2,Class类代表java类,它的实例对象分别对应什么呢?
1,对应各个类在内存中字节码,例如,String类的字节码,Person类的字节码等。。。
2,一个类被类加载器加载到内存中,占用一片存储空间,这个空间的内容就是类的字节码,不同的类的字节码是不同的,
所以它们在内存中的内容是不同的,这一个个空间分别用一个个的对象来表示,这些对象具有相同的类型即Class类型。
3,如何得到各个字节码对应的实例对象(Class类型)
有3中方式:
1:类名.class;例如:System.class
2:对象名.getClass();例如:new Date().getClass()3:Class.forName(类的全名称(包名+类名)字符串);例如:Class.forName("java.util.Date");
4,九个预定义Class实例对象:
1,boolean.class = Boolean.TYPE,
2,char.class = Character.TYPE,
3,byte.class = Byte.TYPE,
4,short.class = Short.TYPE,
5,int.class = Integer.TYPE,
6,long.class = Long.TYPE,
7,float.class = Float.TYPE,
8,double.class = Double.TYPE,
9,void.class = Void.TYPE
5,数组类型的Class对象实例对象
1,Class.isArray()
2,总之,只要好似在源程序中出现的类型,都有各自的Class实例对象,例如,int[]
构造函数的反射应用
一,Constructor类代表某个类中的一个构造方法
二,得到某个类所有的构造方法:
示例:Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
三,得到某一个构造方法://获取时要用到参数类型
示例:Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
四,创建示例对象:
示例:
1,普通方式:String str = new String(new StringBuffer("abc"));
2,反射方式:
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
String str = (String)constructor.newInstance(new StringBuffer("abc"));
五,Class.newInstance()方法:
1,示例:String obj = (String)Class.forName("java.lang.String").newInstance();
2,该方法内部先得到默认的构造方法,然后用该构造方法来创建实例对象。
3,该方法内部的具体事项代码,用到了缓存机制来保存默认构造方法的示例对象。
构造函数反射的示例代码:
成员变量的反射
Field类表示某个类中的一个成员变量。
语法:
类名 对象名 = new 类();
Field field = 对象名.getClass().getField(属性名字符串);
此时field对象并不代表具体的值,只代表该类下的成员变量的一个对象,
要获取到指定对象里的成员变量的值,语法如下:
field.get(对象名);指明要取的成员变量的值属于哪个对象里的。
注:一,getField()和getDeclareField()方法的区别:
getField()方法只能获取到访问级别为可见的属性,不能获取到不可见的属性,若调用该方法
获取不可见的属性,会报出:notFoundFieldException的异常。
getDeclareField()方法可以获取该类中声明的所有属性,包括private所修饰的。
二,使用Field 对象下的get(对象名)来获取该对象下的属性时,如果属性的访问修饰符为不可见时,
则会报出IllegaAccessException()异常。若要获得不可见的属性的话,可以用以下的方式来强行
获得,Field对象名.setAccessible(true);设置访问级别为可见。(称为暴力反射)
例子:将一个类中的所有String类型中的"b"全部换成"a";
注:字节码比较时,要用"=="来比较,因为是同一份字节码。
成员变量反射的实例代码:
成员方法的反射
Method代表某一个类中的一个成员方法
语法:
Class cls = TestUtil1.class;
TestUtil1 tu1 = (TestUtil1)cls.newInstance();
Method method = cls.getDeclaredMethod("show", null);//指定获取方法名为“show”,并且没有参数的方法
method.invoke(tu1, null);//在对象tu1中执行无参的方法
Method method2 = cls.getDeclaredMethod("show2", null);
method2.invoke(null, null);//当对象参数为null时,表示这是一个静态方法
调用方法的方式:
一,使用对象名.方法名。调用;
二,使用反射来获得对应的方法对象,来调用invoke(Object obj,Object...args)执行方法;
其中obj是指那一个对象上的方法,args是表示该方法的参数列表
注:专家模式:哪个类拥有该方法需要的私有数据,那这个方法就属于哪个类。
用反射调用某个类的main方法
语法:
String className = args[0];//获取第一个参数,首先要设置RunConfigurations中的Arguments为要执行的类的完整类名。
Class cls2 = Class.forName(className);//通过活动到的完整类名,获得该类的字节码
Method main = cls2.getMethod("main", new String[]{}.getClass());//通过字节码,获得该类的main方法
/*
* 因为为了兼容JDK1.4以下的版本,在传入参数的时候,会对参数进行装包;执行时,会对参数进行拆包,如果
* 单纯的传入一个数组的话,则在拆包的时候将每一个元素都拆成一个参数,此时会报出:IllegalArgumentException异常
* 解决方式有以下2种。
*/
//使用一个Object数组,再把传入的数组参数当成Object数组的一个元素在传入。
//main.invoke(null, new Object[]{new String[]{"abc","东方","123"}});
//将传入的参数强转成Object对象,
main.invoke(null, (Object)new String[]{"abc","东方","123"});
成员方法反射的示例代码:
数组的反射,及数组与Object
数组的反射
1,具有相同位数(例如:一维对一维)和元素类型的数组属于同一个类型,即具有相同的Class实例对象
2,代表数字的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class
3,基本类型的一维数组可以被当做Object类型使用,不能当作Object[]类型使用;
非基本类型的一维数组,既可以当作Object类型使用,又可以当作Object[]类型使用。
4,Arrays.asList()方法处理int[]和String[]的差异
当处理的是一维的基本数据类型的数组时,其保存的是一维数组的完整名称,即内存中的地址如:[I @a6d7f3。但二维的基本数据类型数组是可以遍历的。
当处理的是引用类型的数组,则会将每一个元素都保存到集合中。
5,Array工具类用于完成对数组的反射操作。
6,通过反射获取元素的步骤:
1,获取数组的字节码:对象.getClass()
2,判断是否是数组:字节码对象.isArray()
3,获取数组的长度:getlength(Object obj)
4,遍历数组元素
5,通过元素.getClass().getName()方法获取元素对应的类型
数组反射的示例代码:
---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
- ——java中的反射
- java基础知识—Java中的反射机制
- Java中的反射——(1)什么是反射
- 黑马程序员——Java中的反射
- 黑马程序员——java中的反射
- 黑马程序员——java中的反射
- 黑马程序员——java中的反射
- 黑马程序员—Java中的反射机制
- java学习——java中的反射学习笔记
- Java调用private方法—Java中的类反射机制
- 黑马程序员——java中的枚举和反射初探
- 黑马程序员——java中的反射技术再探
- 黑马程序员——java中的反射机制
- 黑马程序员——Java中的反射的基本简介
- 黑马程序员——Java中的反射技术
- 黑马程序员——Java中的反射技术
- java学习笔记.01——反射中的JavaBean
- Java中的反射机制——动态编程
- hdu 4873 Java大数
- 宏定义
- 新人来报道
- C++STL之非变异算法
- 计算机视觉与图像处理、模式识别、机器学习学科之间的关系
- ——java中的反射
- flex柱状图
- Swift源码分析----swift-object-replicator(2)
- effective java (8) 覆盖equals时请遵守通用约定
- 结构体数组
- poj 1988 并查集
- 多队列 网卡 收发包 DMA
- HDU 4876 ZCC loves cards(暴力剪枝)
- eclipse出现 annotations.jar missing错误的解决办法