java笔记-高新技术-反射

反射的基石-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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值