欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

Java 反射机制,

来源: javaer 分享于  点击 4063 次 点评:147

Java 反射机制,


反射的概念

1、反射被看作是动态语言的关键,反射机制允许程序在执行期间借助Reflect的API取得任何类的内部信息以及操作内部属性和方法。

Class类

1、Class类被定义为反射的源头。在Object类中定义了public final Class getClass(){}这个方法来获取运行时类Class,这个Class可以保存类的运行时信息。

2、有了反射,可以通过反射创建一个对象,并调用其中的结构。一般来说,有三种方法来获取对象的运行时类Class

先建立一个User类,这个User 定义一些成员变量,成员方法等

<span >package com.reflect;
public class User {
  private String userName;
  private int age;
  public User() {}
  public User(String userName, int age) {
    super();
    this.userName = userName;
    this.age = age;
 }
  public String doWork(String work){
      return "the User is working with"+work;
  }
}</span>
下面就是创建运行时类的三种方法

a、调用运行时类的本身的Class属性

<span >Class clazz=User.class;</span>

b、通过运行时类对象

<span >User u=new User();
Class clazz=u.getClass();</span>

c、通过Class的静态方法

<span >Class clazz=Class.forName("com.reflect.User");</span>
当创建了运行时类Class以后,可以通过反射来获取类的信息,以及调用类的方法。

java.lang.reflect

1、这个包是用来分析类的相关信息,可以通过这个包里面的Field、Method、Constructor这三个类来实现对类信息的动态捕获。

2、java.lang.reflect.Field使用方法,类里的方法主要是用来获取类的成员变量如下例子:

package com.reflect;
import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Field;
public class reflect_demo {
	public static void main(String[] args) {
		Class clazz=User.class;
		Field [] fields=clazz.getDeclaredFields();//获取声明的所有属性
		//Field fields=clazz.getDeclaredField("age");//获取声明为age的属性
		//Field [] fields=clazz.getFields();//获取为访问权限为public的属性
		//clazz.getField("age");//获取访问权限为public且声明为age的属性
		for (Field field : fields) {
			String name=field.getName();//获取属性名
			int modify=field.getModifiers();			
		}
	}
}

3、java.lang.reflect.Method使用方法,主要是用来获取类的成员方法

package com.reflect;
import java.lang.reflect.Method;
public class reflect_demo {
	public static void main(String[] args) throws Exception{
		Class clazz=User.class;
		Method [] methods=clazz.getMethods();//获取所有的public方法
//		Method  method=clazz.getMethod("work");
//		Method [] methods=clazz.getDeclaredMethods();//获取类声明的所有方法
//		Method  method=clazz.getDeclaredMethod("work");
		for (Method method : methods) {
			String name=method.getName();//方法名
			String returnType=method.getReturnType().getName();//方法返回类型
			Class [] params=method.getParameterTypes();//方法形参列表
			int modify=method.getModifiers();//方法权限修饰
		    Class [] exceptions=method.getExceptionTypes();//抛出异常列表
		}
		//动态调用一个方法
		Method method=clazz.getDeclaredMethod("doWork", String.class);
		Object result=method.invoke(clazz.newInstance(), "teacher");
	}
}
上面对于Method类的方法只列举了一些重要常用的,其它方法可以参考JDK API查看

4、java.lang.reflect.Constructor使用方法

<span >package com.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class reflect_demo {
	public static void main(String[] args) throws Exception{
		Class clazz=User.class;
		Constructor [] constructors=clazz.getConstructors();//获取声明为public的构造函数
		//Constructor [] constructor=clazz.getDeclaredConstructors();//获取所有的构造函数
	}
}</span>
Constructor的其它方法与Method类的方法有些类似此外就不再详细叙述,有兴趣的可以参考JDK API

反射的应用

反射的动态语言的关键,java中的一个重要的动态代理就是用反射来实现的,下面就是动态代理的简单实现过程

<span >package com.reflect;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理的使用,反射是动态语言的关键
interface Subject{
	public void action();
}
//被代理类
class RealSubject implements Subject{
	@Override
	public void action() {
		System.out.println("我是被代理的对象类,被代理执行");
	}
}
//接口
interface ClothFactory {

	public void productCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory{

	@Override
	public void productCloth() {
		System.out.println("Nike工厂生产一批衣服");
	}	
}
class MyInvocationHandler implements InvocationHandler{
	Object obj;//实现了接口被代理类的对象的声明
	//给被代理类的对象实例化,返回一个代理类的对象
	public Object blind(Object obj){
		this.obj=obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}
	//当通过代理类的对象发起对被重写的方法调用时,都会转换为对如下的invoke方法的调用
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		//method方法的返回值是returnVal
		Object returnVal= method.invoke(obj, args);
		return returnVal;
	}
}
public class TestProxy {
	public static void main(String[] args) {
		//1、被代理类的对象、
		RealSubject real=new RealSubject();
		//2、创建一个实现了InvocationHandler接口的类对象
		MyInvocationHandler handler=new MyInvocationHandler();
		//3、调用blind方法,动态的返回一个同样实现了real所在类实现的接口的代理类的对象 
		Object obj=handler.blind(real);
		Subject sub=(Subject)obj;//此时sub就是代理类对象
		//4、
		sub.action();//转到对InvocationHandler接口的实现类Invoke方法的调用 
		//
		NikeClothFactory nike=new NikeClothFactory();//创建被代理对象
		ClothFactory proxyCloth=(ClothFactory) handler.blind(nike);
		proxyCloth.productCloth();
	}
}</span>



相关文章

    暂无相关文章
相关栏目:

用户点评