您的位置:首页 > 编程语言 > Java开发

java笔记-高新技术-反射

2014-08-19 15:47 459 查看
反射的基石-Class类
反射就是把java类中的各种成分映射成相应的java类,java反射机制就是在运行状态中,对于任意个类,都能够知道这个类 的所有属性和方法;对于任意一个对象,都能够调

它的任意一个方法和属性,这种动态获取信息以及动态调用对象的方法的功能称之为java语言的反射机制。

该机制允许程序通过Reflect APIs取得任何已知名称的class的内部信息,例如modifiers(public ,private),superclass(object),interface(Cloneable),也包括基本数据类型,

机制可于运行时改变fields内容和methods。

关于动态语言:一般认为,程序在运行时,可改变程序的结构或者变量类型的语言。

java因有了Reflect,使其具有动态语言的特性,我么可以在程序运行时,加载使用编译期间完全位置的classes,即java可以加载在运行时才得知名称的class并获得其完整构造,生成对象实体,设置field,访问method。这种看透class的能力被称为Introspection(内省)。

Class的产生:当一个类被加载或被jvm调用,jvm会自动产生一个Class object。由于Class的构造方法是私有的,所以不能通过自定义对象的方式产

Class object 诞生管道
示例
运用getClass()
注:每个class 都有此函数
String str = "abc";
Class c1 = str.getClass();
运用
Class.getSuperclass()2
Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
运用static method
Class.forName()
(最常被使用)
Class c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName ("[I");
运用
.class 语法
Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
运用
primitive wrapper classes
的TYPE 语法
 
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;
java反射机制的主要功能:

1.在运行时判断任意一个对象所属的类;

2.在运行时构造任意一个类的对象;

3.在运行时判断任意一个类所具有的成员变量和方法;

4.在运行时调用任意一个对象的方法;

5.生成动态代理。

字节码:当类被加载到内存中,占用内存中的一片空间,该空间里面的内容就是类的字节码,不同类的字节码是不同的。

获取字段值:

package net.csing;
import java.lang.reflect.*;
public class FieldDemo {

/**
* @param args
*/
public static void main(String[] args){
//创建要操作的对象。
ReflectPoint rf=new ReflectPoint(2,3);
try{
/*
* 获取public字段的值。
*/
Field fx=rf.getClass().getField("x");
//获取字段fx所对应的在某对象rf上的值
System.out.println("x:"+fx.get(rf));
/*
* 获取private字段的值。
*/
Field fy=rf.getClass().getDeclaredField("y");
fy.setAccessible(true);
//获取字段f所对应的在某对象rf上的值
System.out.println("y:"+fy.get(rf));

}
catch(Exception e){
throw new RuntimeException("error.");
}
}

}
class ReflectPoint{
public int x;
private int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
}
字段遍历及字符替换

package net.csing;
import java.lang.reflect.*;
public class FieldDemo {

/**
* @param args
*/
public static void main(String[] args){
//创建要操作的对象。
ReflectPoint rf=new ReflectPoint(2,3);
try{
/*
* 获取public字段的值。
*/
Field fx=rf.getClass().getField("x");
//获取字段fx所对应的在某对象rf上的值
System.out.println("x:"+fx.get(rf));
/*
* 获取private字段的值。
*/
Field fy=rf.getClass().getDeclaredField("y");
fy.setAccessible(true);
//获取字段f所对应的在某对象rf上的值
System.out.println("y:"+fy.get(rf));
/*
* 将对象对应的字段中的含有b的字符串全部替换成a
*/
changeStringChar(rf);
//打印结果
System.out.println(rf);
}
catch(Exception e){
throw new RuntimeException("error.");
}
}

private static void changeStringChar(ReflectPoint rf) {
/*
* 获取对像对应的所有字段。
*/
Field[] field=rf.getClass().getFields();
try{
//遍历字段。
for(Field f:field ){
//筛选string字段。
if(f.getType()==String.class){
//获得字段对应的值。
String oldStr=(String)f.get(rf);
//将b替换为a
String newStr=oldStr.replace('b', 'a');
//将替换后的结果写入对象。
f.set(rf,newStr);
}
}
}
catch(Exception e){
throw new RuntimeException("error.");
}
}
}
//操作字段的反射类。
class ReflectPoint{
public int x;
private int y;
public String str1="abcdefg";
public String str2="abcdefgijkla";
public String str3="efg";
//初始化x,y
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
//重写该类对应的toString方法。
public String toString(){
return str1+":"+str2+":"+str3;
}
}
反射的作用:实现框架功能

框架与工具类有区别:工具类被用户的类调用;而框架则调用用户提供的类。

用户要用框架,则框架如何调用随后用户书写的类,此时需要用到反射。

javabean实例

javabean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有 的字段,如果要在两个模块间传递多个信息,可将该信息封装到javabean中,这些信息在类中用私有字段来存储。javabean的属性是根据方法名来判断出来的,一般如getName去掉get,Name即是属性名。jdk中提供了对javabean操作的api,这套api称为内省,用内省来访问私有化的成员和变量非常方便。

package csing.net;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IntroSpectionDemo {

/**
* @param args
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static void main(String[] args) throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ReflectDemo rd=new ReflectDemo(6,9);
String propertyName="x";
/*
* PropertyDescriptor:描述javabean中propertyName的属性。
*/
//获得属性对象。
PropertyDescriptor pd=new PropertyDescriptor(propertyName,rd.getClass());
//获得propertyName对应的方法。
Method methodGetX=pd.getReadMethod();
try {
//使用方法获取X的值。
Object retVal=methodGetX.invoke(rd);
System.out.println(retVal);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/*
* 获取设置属性的方法。
*/
Method methodSetX=pd.getWriteMethod();
//方法引用。
methodSetX.invoke(rd, 19);
//获取方法,取得值。
int retVal2=rd.getX();
System.out.println(retVal2);
//通过beanInfo可获得对象对应的属性,方法等。
BeanInfo bi=Introspector.getBeanInfo(rd.getClass());	//根据对象获得Class
//获得属性集
PropertyDescriptor[] pd2=bi.getPropertyDescriptors();
//遍历属性集
for(PropertyDescriptor p:pd2){
System.out.println("get read method:");
if(p.getName().equals(propertyName)){
//获得特定的属性。
System.out.println("I got his name:"+p.getName());
}
//获得对象的get方法。
Method m=p.getReadMethod();
Object get_x=m.invoke(rd);
System.out.println(get_x);
}
}

}
//反射测试类。
class ReflectDemo{
public ReflectDemo(int x, int y) {
super();
this.x = x;
this.y = y;
}
private int x=0;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
private int y=0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: