首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

JAVA基础加固加强 enhance day1反射 reflect

2012-09-21 
JAVA基础巩固加强 enhance day1反射 reflect以前一直只知道有reflect这么一个类是用来反射的,听人家说java

JAVA基础巩固加强 enhance day1反射 reflect

以前一直只知道有reflect这么一个类是用来反射的,听人家说java中的反射很难,晚上听罢张老师讲的反射这一节的内容,惶然大悟,原来反射就是把Java类中的各种成分映射成相应的java类。 ???
??? 反射的基础是要掌握Class这个类的,具体Class的类是干什么的,下面是api文档中的解释

??? api中关于Class类的一段描述Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects. 翻译成中文Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。

??? 可以看出Class类就是一个类或者接口对象的一个实例在内存中的字节码,而如何得到一个类的字节码呢?其方法有三:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1???? ??? Class<??extends?String>?cls1?=?str1.getClass();
2?????????Class<String>?cls2?=?String.class;
3?????????Class<?>?cls3?=?Class.forName("java.lang.String");

??? 而Class的isPrimitive()方法就是用来判断一个类的字节码是不是9个预定义的class
????
??? 接下来是Constructor类,Constructor类代表某个类中的一个构造方法。
?? 得到某个类所有的构造方法: 例子:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Constructor?[]?constructors=?Class.forName("java.lang.String").getConstructors();????? 得到某一个构造方法:
?? 例子:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Constructor?constructor?=?Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//获得方法时要用到类型?
??? 创建实例对象:<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->//通常方式:
String?str?=?new?String(new?StringBuffer("abc"));
????
//反射方式:?
String?str?=?(String)constructor.newInstance(new?StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象?????? Class.newInstance()方法:
?? 例子:<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->String?obj?=?(String)Class.forName("java.lang.String").newInstance();??? 该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
?? 该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。???

下面是一个Field反射的综合实例
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。?首先定义一个ReflectPoint的类
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->?1?package?com.anduo.day1;
?2?
?3?public?class?ReflectPoint?{
?4?????private?int?x;
?5?????public?int?y;
?6?????public?String?a?=?"ball";
?7?????public?String?b?=?"basketball";
?8?????public?String?c?=?"hello";
?9?
10?????public?ReflectPoint(int?x,?int?y)?{
11?????????super();
12?????????this.x?=?x;
13?????????this.y?=?y;
14?????}
15?
16?????@Override
17?????public?String?toString()?{
18?????????return?"a="?+?a?+?";b="?+?b?+?";c="?+?c;
19?????}
20?}
21?
下面的步骤是:先从对象中得到所有为String类型的字段,2:得到Sting字段的值;3:用String类的replace方法代换a字符为b字符;4:把对象的String字段设置为修改完的新String。
齐活儿
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->?1?package?com.anduo.day1;
?2?
?3?import?java.lang.reflect.Constructor;
?4?import?java.lang.reflect.Field;
?5?
?6?public?class?ReflectTest?{
?7?
?8?????
?9?????public?static?void?main(String[]?args)?throws?Exception?{
10?
11?????????
12?????????/**
13??????????*?成员变量的反射?Field
14??????????*/
15?????????System.out.println("**成员变量的反射?Field**");
16?????????ReflectPoint?pt1?=?new?ReflectPoint(1,?-1);
17?????????Field?fieldY?=?pt1.getClass().getField("y");
18?????????//?fieldY?不是对象身上的变量,而是类上,要用它来去对象上字段的值
19?????????System.out.println("p1?中??y?=?"?+?fieldY.get(pt1));
20?????????Field?fieldX?=?pt1.getClass().getDeclaredField("x");//?获取私有属性字段
21?????????fieldX.setAccessible(true);//?暴力反射
22?????????System.out.println("p1?中??x?=?"?+?fieldX.get(pt1));
23?
24?????????/**
25??????????*?将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
26??????????*/
27?????????changeStringValue(pt1);
28?????????System.out.println(pt1);
29?????}
30?
31?????/**
32??????*?将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
33??????*?@param?obj
34??????*?@throws?IllegalArgumentException
35??????*?@throws?IllegalAccessException
36??????*/
37?????private?static?void?changeStringValue(Object?obj)?throws?IllegalArgumentException,?IllegalAccessException?{
38?????????Field[]?fields?=?obj.getClass().getFields();
39?????????for?(Field?field?:?fields)?{
40?????????????//?if(field.getType().equals(String.class))
41?????????????if?(field.getType()?==?String.class)?{
42?????????????????String?oldValue?=?(String)?field.get(obj);
43?????????????????String?newValue?=?oldValue.replace('a',?'b');
44?????????????????field.set(obj,?newValue);
45?????????????}
46?????????}
47?????}
48?
49?}
50?结果如下
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->**成员变量的反射?Field**
p1?中??y?=?-1
p1?中??x?=?1
a=bbll;b=bbsketbbll;c=hello
综上可以看出,其实反射也没多难,人家那些写框架的也不就是用了些反射吗?把配置文件中的东西读出来,然后再调用下面的类去做应该做的事情,当然这个过程就用到了反射了。

热点排行