java反射技术
java反射技术
Last modified:2013-04-06 23:45:44
***************************************
获得Class对象的方法:
Person.class:类名.class
new Person().getClass():对象.getClass()
Class.forName("java.lang.String"):Class.forName(完整类名)。(作用:获得类的字节码。有两种情况:如果这个类在内存中,则直接返回;如果内存中没有则通过类加载器加载到虚拟机内存中。以后要得到这个字节码就不用再加载了。在反射中主要使用这种方法,因为在写源程序的时候还不知道类的名字,也就是说我们可以使用一个变量来代替。)
一个字节码可以创建出多个实例对象来。
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
只要是类型就对应一个Class实例对象。有九个预定义的Class对象:八个基本类型加一个void(空类型)。
Primitive Data Type:原生数据类型。
int.class.isPrimitive():isPrimitive(原始的)是否是基本数据类型。
Integer.TYPE:代表他所包装的那个基本数据类型的那份字节码,也就是基本数据类型的 Class对象(int.class)
数组不是基本数据类型(Primitive Data Type),是引用类型,判断是否是数组可以使用:isArray();
总之,只要是在源程序中出现的类型,都有各自的一份Class实例对象,例如:int[],void,String,int ……
反射(Reflect):
反射:就是把java类中的各种成分映射成相应的java类。
例如:一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类,表示java类的Class类显然要提供依系列的方法,来获得其中的变量,方法,构造函数,修饰符,包等信息,这些信息就是用相应类的实例对象表示,它们是Field,Method,Contructor,Package等等。
通过反射,我们可以得到各个类中相应成分的Class对象。
编译时与运行时的区别:
编译时,检查代码的语法错误。不能检查逻辑错误!
运行时,如果代码存在逻辑错误,那么就会报错。
Alt+shift+s:快速生成代码。
Constructor:
我们可以通过反射创建对象。
String str = new String("abc");
String str =
(String) String.class.getConstructor(StringBuffer.class)
.newInstance(new StringBuffer("abcde"));
如果通过空参数的构造方法创建一个对象,还可以通过Class.newInstance()方法。
例如:
String str =
(String)Class.forName("java.lang.Stirng").newInstance();
Field:
获得Field类对象:Field field = pt1.class.getField("字段名");
获得某个实例的字段值:field.get(pt1);
getField方法不能获得私有字段,想要获得可以通过getDeclaredField("字段名")(不论该字段可见不可见都能获得该字段的对象)。想要获取字段的值,可以先执行field.setAccessible(ture);然后再get(pt1),这就是所谓的暴力反射。
英文词汇:declared:声明的;Accessible:可接近,可到达;
public static void changeChar(Object obj) throws Exception { Field[] fields = obj.getClass().getDeclaredFields();//能看见所有的字段,包括私有的。 for (Field field : fields) { if (field.getType() == String.class) { field.setAccessible(true);//暴力反射; String oldValue = (String) field.get(obj); String newValue = oldValue.replace('a', 'b'); field.set(obj, newValue); } } }
对字节码的比较用“==”!当然用equals也可以。但是“==”更加合适!因为是同一份字节码。
Method:
方法与对象是没有关系的。我们通过获得方法对象后,再通过这个方法对象调用某个类执行这个方法。也就是先得到这个方法,然后在针对某个对象去调用这个方法。
通过反射的方式获得某个字节码里的方法对象,再用这个方法对象去作用于某个对象。
invoke:恳求;
调用方法:
通常:str.charAt(1);
反射:
Method methodCharAt =Class.forName("java.lang.String").getMethod("charAt",int.class); methodCharAt.invoke(str,1);
由方法去调用对象执行该方法。这是面向对象的思维模式,其实只是这个方法对象给str对象发出了一个恳求,请求被执行。之后str对象就发出一个执行该方法的信号。比如:司机刹车,司机其实是踩了刹车板,给汽车发了一个信号,汽车就进行刹车。到底是如何将车停下的,汽车的刹车方法最清楚!这里就是方法恳求被执行,对象发出信号执行它!
注意:如果Method对象第一个参数为null,说明这个Method对象对应一个静态方法。
上一篇: JDK 5.0(Tiger)中的一些新特性(3):可变参数
下一篇: JAVA的内部类和静态内部类
推荐阅读
-
2021年艾瑞深中国高职院校排行榜-2021年中国职业技术大学排行榜
-
Android Caused by: java.lang.ClassNotFoundException解决办法
-
MyEclipse8.5导入java项目后会出现红色波浪线怎么办?
-
利用Java如何获取IP与机器名方法示例
-
Java语言概述
-
java计算两个日期之前的天数实例(排除节假日和周末)
-
java 使用memcached以及spring 配置memcached完整实例代码
-
Java Web使用Html5 FormData实现多文件上传功能
-
JAVA反射练习
-
Excel Services OverView系列2 使用Excel Web Access技术在线浏览Excel工作薄