`
代码小达人
  • 浏览: 24468 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

java

阅读更多
1.反射的概念
    在原来传统观念里,我们是先创建对象,然后根据对象来调用其方法,但是反射机制颠覆了我们原来的观念,反射能直接对于一个未知的其信息的类(如动态装载进来的类)根据一系列的方法的调用得到该类的属性和方法。
2.反射的具体实现
     反射机制其实是用到了JAVA API中Reflection这个类,通过Reflection APIs我们可以取得任何一个已知名称的class的内部信息,包括限定符,接口,继承类等,因此在获得其方法或者属性也可以通过构造器直接改变它的方法和属性。另外,Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组成部分。具体代码如下:

package 反射代码;
/**
 * 机动车接口定义
 * @author a
 *
 */
public interface IVehicle {
	
	public void startMe();//启动
	
	public int forward(int dins);//前进
	//有多少油
	public int getEnergy();
	
}
package 反射代码;

public class BMW implements IVehicle {
	public static final String company="宝马公司";
	public int energy;//能量

	public BMW(){
		this.energy=10;
	}
	public BMW(int energy){
		this.energy=energy;
	}
	//启动
	public void startMe() {
		System.out.println("BMW启动....");
		
	}
	//前进
	public int forward(int dins) {
		energy-=dins/100;
		System.out.println("BMW前进"+dins);
		return energy;
	}

	//有多少能量
	public int getEnergy() {

		return this.energy;
	}
	

}


package 反射代码;

import java.lang.reflect.Modifier;

public class ReflectionTest {
	public static void main(String args[]) {
		try {
			// 1.载入类对象
			Class c = Class.forName("反射代码.BMW");
			// 2.调用默认无参构造器生成对象
			Object object = c.newInstance();
			// 传入对象进行反射操作
			ReflectionTest.RegetClass(c);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void RegetClass(Class c) {
		String className = c.getName();
		System.out.println("类的名字是: " + className);
		// 得到类中的方法对象数组
		java.lang.reflect.Method[] methods = c.getMethods();
		// 得到类定义的构造器对象数组
		java.lang.reflect.Constructor[] cons = c.getConstructors();
		// 得到类定义的属性对象数组
		java.lang.reflect.Field[] fields = c.getFields();
		// 得到类的直接父类类对象
		Class superClass = c.getSuperclass();
		// 得到类所有实现的接口类对象数组
		Class[] interfaces = c.getInterfaces();
		// 具体得到其属性及方法还有继承类接口等的方法调用
		ReflectionTest.printFiledInfo(fields);
		ReflectionTest.printInterface(interfaces);
		ReflectionTest.printMethodInfo(methods);
		ReflectionTest.printSuper(superClass);
	}

	private static void printFiledInfo(java.lang.reflect.Field[] fields) {
		System.out.println("共有属性:" + fields.length);
		for (java.lang.reflect.Field f : fields) {
			String fName = f.getName();
			Class fType = f.getType();
			System.out.println("属性类型是:" + fType);
			// 得到属性的访问限定符
			int mType = f.getModifiers();
			// 判断是何种限定符
			if (Modifier.isPublic(mType))
				System.out.println(" public");
			if (Modifier.isAbstract(mType))
				System.out.println("  abstract");
			if (Modifier.isFinal(mType))
				System.out.println(" final");
		}
	}

	private static void printInterface(Class[] interfaces) {
		for (Class c : interfaces) {
			System.out.println("接口名:" + c.getName());
			Class[] cs = c.getInterfaces();
			printInterface(cs);
		}
	}

	private static void printSuper(Class superClass) {
		System.out.println("接口名: " + superClass.getName());
		Class ss = superClass.getSuperclass();
		if (null != ss) {
			printSuper(ss);
		}

	}

	private static void printMethodInfo(java.lang.reflect.Method[] methods) {
		for (java.lang.reflect.Method m : methods) {
			int t = m.getModifiers();
			System.out.println("限定符是: " + t);
			String name = m.getName();
			System.out.println("方法名是: " + name);
			Class returnType = m.getReturnType();
			System.out.println("返回值类型是: " + returnType.getName());
			// 参数类型组....
			Class ps[] = m.getParameterTypes();
			// 异常类型组...
			Class es[] = m.getExceptionTypes();
		}
	}
}




输出结果:
类的名字是: 反射代码.BMW
共有属性:2
属性类型是:class java.lang.String
public
final
属性类型是:int
public
接口名:反射代码.IVehicle
限定符是: 1
方法名是: startMe
返回值类型是: void
限定符是: 1
方法名是: forward
返回值类型是: int
限定符是: 1
方法名是: getEnergy
返回值类型是: int
限定符是: 273
方法名是: wait
返回值类型是: void
限定符是: 17
方法名是: wait
返回值类型是: void
限定符是: 17
方法名是: wait
返回值类型是: void
限定符是: 1
方法名是: equals
返回值类型是: boolean
限定符是: 1
方法名是: toString
返回值类型是: java.lang.String
限定符是: 257
方法名是: hashCode
返回值类型是: int
限定符是: 273
方法名是: getClass
返回值类型是: java.lang.Class
限定符是: 273
方法名是: notify
返回值类型是: void
限定符是: 273
方法名是: notifyAll
返回值类型是: void
接口名: java.lang.Object



利用反射机制,我们还可以实现在对象上调用方法,具体实现代码如下:


/**
	 * 调用对象的方法
	 * @param bmw:要调用的对象
	 * @param destName:要调用的对象的名字
	 * @param paraType:方法参数类型列表
	 */
	public static void invokeTest(BMW bmw,String destName,Class ...paraType){
		try{
			//得到对象所在的类
			Class destClass = BMW.class;
			//查询要调用的方法对象
			Method destM=destClass.getMethod(destName, paraType);
			if(null!=destM){
				//调用方法,传入参数
				Object obj= destM.invoke(destName, paraType);
				System.out.println(destM+"调用结果是"+obj);
			}
		}catch(Exception ef){
			ef.printStackTrace();
		}
	}



这样可以利用方法反过来调用对象.

3.反射的应用范围
  在运行时判定任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判定任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理,便于程序员进行操作。
IOC:
设计模式中IOC就是利用了这个反射机制,可以把IOC模式看做是工厂模式的升华,可以把IOC看作是一个大工厂,只不过这个大工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java 的“反射”编程,根据XML中给出的类名动态装载生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由XML文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。
  AOP:
同样,反射机制还可以用于AOP代理模式,就只需修改代理类中的方法,而不必修改对象“原类”中的代码。因此代理类的构造显得尤为重要,InvocationHandler是代理实例的调用处理程序实现的接口每个代理实例都具有一个关联的调用处理程序,对代理实例调用方法时将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法。因此以后客户端只需调用代理类来完成所需的工作,而不用直接接触源代码。
具体代码如下:
package 反射代码;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class DebugVehicleProxy implements InvocationHandler {
	// 被代理的对象
	private Object obj;

	// 得到代理的对象
	public static Object getProxy(Object obj) {
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj
				.getClass().getInterfaces(), new DebugVehicleProxy(obj));
	}

	private DebugVehicleProxy(Object obj) {
		this.obj = obj;
	}

	/**
	 * 实现InvocationHandler中的方法 被代理类调用时,实际上是通过这个方法调用的
	 * 
	 * @param proxy:被调用方法的对象
	 * @param m:要调用的方法对象
	 * @param args:调用方法的参数列表
	 */
	public Object invoke(Object proxy, Method m, Object[] args)
			throws Throwable {
		Object result;
		try {
			System.out.println("debug advice begin:" + m.getName());
			result = m.invoke(obj, args);// 调用实际对象的方法
		} catch (InvocationTargetException e) {
			throw e.getTargetException();
		} catch (Exception e) {
			throw new RuntimeException("invocation:" + e.getMessage());
		} finally {
			System.out.println("debug advice finish:" + m.getName());
		}

		return result;
	}

}

分享到:
评论

相关推荐

    JAVA_API1.6文档(中文)

    java.lang.management 提供管理接口,用于监视和管理 Java 虚拟机以及 Java 虚拟机在其上运行的操作系统。 java.lang.ref 提供了引用对象类,支持在某种程度上与垃圾回收器之间的交互。 java.lang.reflect 提供类...

    java源码包---java 源码 大量 实例

    Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这款实例会对你有所帮助。 Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM...

    Java 面经手册·小傅哥.pdf

    这是一本以面试题为入口讲解 Java 核心内容的技术书籍,书中内容极力的向你证实代码是对数学逻辑的具体实现。当你仔细阅读书籍时,会发现Java中有大量的数学知识,包括:扰动函数、负载因子、拉链寻址、开放寻址、...

    Java OCR 图像智能字符识别技术,可识别中文

    Java OCR(Optical Character Recognition,光学字符识别)技术是一种计算机视觉领域的应用,它能将图像中的文字转换成可编辑的文本格式。这项技术在各种场景下都有广泛应用,比如文档扫描、车牌识别、发票处理等。...

    Java API文档 中文网页版

    Java API文档是Java开发者的重要参考资料,它包含了Java开发工具包(JDK)中的所有类、接口、方法和常量的详细说明。这份中文网页版的Java API文档为中国的开发者提供了便利,无需通过英文版本来学习和查找API信息,...

    java_011 java 人脸识别完整源代码

    java_011 java 人脸识别完整源代码java_011 java 人脸识别完整源代码java_011 java 人脸识别完整源代码java_011 java 人脸识别完整源代码java_011 java 人脸识别完整源代码java_011 java 人脸识别完整源代码java_011...

    java电商源代码 java电商源代码

    java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java电商源代码java...

    java api最新7.0

    JAVA开发人员最新版本7.0 api文档!本文档是 Java Platform Standard Edition 7 的 API !Java 1.7 API的中文帮助文档。 深圳电信培训中心 徐海蛟博士教学用api 7.0中文文档。支持全文检索,在线即时查询。 里面列...

    java单机小游戏.zip

    java单机小游戏java单机小游戏java单机小游戏java单机小游戏 java单机小游戏java单机小游戏java单机小游戏java单机小游戏 java单机小游戏java单机小游戏java单机小游戏java单机小游戏 java单机小游戏java单机小游戏...

    java景点导航系统java景点导航系统

    java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点导航系统java景点...

    java简易小游戏.zip

    java简易小游戏java简易小游戏java简易小游戏java简易小游戏 java简易小游戏java简易小游戏java简易小游戏java简易小游戏 java简易小游戏java简易小游戏java简易小游戏java简易小游戏 java简易小游戏java简易小游戏...

    java开源包4

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包9

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    javacv配置+javacv人脸识别代码

    JavaCV(Java Computer Vision)是一个基于Java的计算机视觉库,它为Java和Android开发者提供了方便的接口来使用多个流行的计算机视觉框架,如OpenCV、FFmpeg等。在本项目中,我们将探讨如何配置JavaCV以及如何使用...

    java开源包5

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    java开源包10

    JoSQL(SQLforJavaObjects)为Java开发者提供运用SQL语句来操作Java对象集的能力.利用JoSQL可以像操作数据库中的数据一样对任何Java对象集进行查询,排序,分组。 搜索自动提示 Autotips AutoTips是为解决应用系统对于...

    Java2Pas Java代码转pas代码

    Java2Pas是一个实用工具,主要用于将Java编程语言编写的源代码转换为Pascal语言的等效代码。这个工具对于那些需要在两种语言之间迁移代码或者理解不同编程语言语法的开发者来说非常有价值。Java和Pascal虽然都是面向...

    Java开发技术大全(500个源代码).

    HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 示例描述:本章介绍开发Java的基础语法知识。 ...

    java错误处理:java.lang.OutOfMemoryError: Java heap space

    ### Java 错误处理:java.lang.OutOfMemoryError: Java heap space 在Java应用程序开发过程中,经常遇到的一个问题就是内存溢出错误,特别是在处理大量数据或长时间运行的应用时。其中,“java.lang....

    Java文件管理系统源码.zip

    Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 Java文件管理系统源码 ...

Global site tag (gtag.js) - Google Analytics