Java反射那点事(一)

简介

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

最近在使用JSONArray转化JSON格式的时候,总觉得它使用了Java的反射机制。在Spring中也有一些用到反射的地方,因此,先简单总结一下Java反射基础的一些东西。

代码举例:

说明:新建了一个Person接口,Student类作为测试对象。

1.Person.java

/*
 * $filename: person.java,v $
 * $Date: 2013-11-10  $
 * Copyright (C) ZhengHaibo, Inc. All rights reserved.
 * This software is Made by Zhenghaibo.
 */
package edu.njupt.zhb.reflection;
/*
 *@author: ZhengHaibo  
 *web:     http://blog.csdn.net/nuptboyzhb
 *mail:    zhb931706659@126.com
 *2013-11-10  Nanjing,njupt,China
 */
public interface Person {
	public void say();
}

2.Student.java

/*
 * $filename: Student.java,v $
 * $Date: 2013-11-10  $
 * Copyright (C) ZhengHaibo, Inc. All rights reserved.
 * This software is Made by Zhenghaibo.
 */
package edu.njupt.zhb.reflection;
/*
 *@author: ZhengHaibo  
 *web:     http://blog.csdn.net/nuptboyzhb
 *mail:    zhb931706659@126.com
 *2013-11-10  Nanjing,njupt,China
 */
@Deprecated
public class Student implements Person{
	public boolean isGood;
	private String id;
	private String name;
	public Student(String id, String name) {
		this.id = id;
		this.name = name;
	}
	public Student() {

	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	private void privateMethod(){
		System.out.println("this is a private Method!");
	}
	@Override
	public void say() {
		// TODO Auto-generated method stub
		System.out.println("I am a student,My name is "+name+",My id is "+id);
	}
}

3.测试类

/*
 * $filename: JavaReflectionTest.java,v $
 * $Date: 2013-11-10  $
 * Copyright (C) ZhengHaibo, Inc. All rights reserved.
 * This software is Made by Zhenghaibo.
 * Reference: http://tutorials.jenkov.com/java-reflection/index.html
 */
package edu.njupt.zhb.reflection;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/*
 *@author: ZhengHaibo  
 *web:     http://blog.csdn.net/nuptboyzhb
 *mail:    zhb931706659@126.com
 *2013-11-10  Nanjing,njupt,China
 */
public class JavaReflectionTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		JavaReflectionTest jrt = new JavaReflectionTest();
		System.out.println("--基本信息的输出----------------------------------------------------------------");
		jrt.getBaseInfoByClass();
		System.out.println("--测试构造方法的输出----------------------------------------------------------------");
		jrt.testConstructor();// 输出:I am a student,My name is 郑海波,My id is 1012010638
		System.out.println("--测试invoke方法的输出----------------------------------------------------------------");
		jrt.testMethod();
		System.out.println("--测试获取get和set方法的输出----------------------------------------------------------------");
		jrt.printGettersSetters(Student.class);
		System.out.println("--测试访问私有成员变量和私有函数的输出--------------------------------------------------------");
		jrt.testPrivateFieldAndMethod();
	}

	/**
	 * 基本信息的输出
	 */
	public void getBaseInfoByClass() {
		Class<Student> studentClass = Student.class;// 获得Class对象
		Class<Student> studentClass2 = null;
		try {
			studentClass2 = (Class<Student>)Class.forName("edu.njupt.zhb.reflection.Student");
		} catch (ClassNotFoundException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}//通过forName获得Class对象
		String className = studentClass.getName();// 获得类名
		System.out.println("className=" + className);
		Field[] fields = studentClass.getFields();// 获得public成员变量
		for (Field field : fields) {
			System.out.println("field=" + field);
		}
		Method[] methods = studentClass.getMethods();// 获得成员函数
		for (Method method : methods) {
			System.out.println("method=" + method);
		}
		/**
		 * Modifier.isAbstract(int modifiers) Modifier.isFinal(int modifiers)
		 * Modifier.isInterface(int modifiers) Modifier.isNative(int modifiers)
		 * Modifier.isPrivate(int modifiers) Modifier.isProtected(int modifiers)
		 * Modifier.isPublic(int modifiers) Modifier.isStatic(int modifiers)
		 * Modifier.isStrict(int modifiers) Modifier.isSynchronized(int
		 * modifiers) Modifier.isTransient(int modifiers)
		 * Modifier.isVolatile(int modifiers)
		 */
		int modifier = studentClass.getModifiers();// 获得类的属性
		System.out.println(Modifier.isInterface(modifier));
		Package packagePath = studentClass.getPackage();// 获得类所在包
		System.out.println("packagePath=" + packagePath.getName());
		Class<Object> superclass = (Class<Object>) studentClass.getSuperclass();// 获取类的父类
		System.out.println("superclassName=" + superclass.getName());
		Class[] interfaces = studentClass.getInterfaces();// 获取实现的接口
		for (Class clazz : interfaces) {
			System.out.println("interfaceName=" + clazz.getName());
		}
		Constructor[] constructors = studentClass.getConstructors();// 获取所有的构造方法
		for (Constructor constructor : constructors) {
			System.out.println("constructor=" + constructor);
		}
		Annotation[] annotations = studentClass.getAnnotations();// 获取类的注解
		for (Annotation annotation : annotations){
			System.out.println("annotation=" + annotation);
		}
	}
	/**
	 * 通过反射的方式获取构造方法,并用构造方法生成对象
	 */
	public void testConstructor(){
		Class<Student> studentClass = Student.class;// 获得Class对象
		try {
			Constructor<Student> constructor = (Constructor<Student>)studentClass.getConstructor(String.class,String.class);
			try {
				Student student = constructor.newInstance("1012010638","郑海波");
				student.say();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// 获取所有的构造方法
	}

	/**
	 * 测试反射方式获取的方法,并调用
	 *  输出结果如下;
	 *  I am a student,My name is 郑海波,My id is 1012010638
	 *  id =1012010638 
	 *  I am a student,My name is 郑海波,My id is B08020526
	 */
	public void testMethod(){
		Class<Student> studentClass = Student.class;// 获得Class对象
		try {
			Person person = new Student("1012010638","郑海波");
			Method method = studentClass.getMethod("say");
			method.invoke(person, null);//第一个参数是实体对象,第二个参数是该方法的参数
			Method getMethod = studentClass.getMethod("getId");
			String id = (String)getMethod.invoke(person, null);
			System.out.println("id = "+id);
			Method setMethod = studentClass.getMethod("setId",String.class);//第二个(及以后的)参数为方法的参数类型
			setMethod.invoke(person, "B08020526");
			method.invoke(person, null);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 测试获取类的get和set方法
	 * @param aClass
	 */
	public void printGettersSetters(Class aClass) {
		
		Method[] methods = aClass.getMethods();
		for (Method method : methods) {
			if (isGetter(method))
				System.out.println("getter: " + method);
			if (isSetter(method))
				System.out.println("setter: " + method);
		}
	}

	private boolean isGetter(Method method) {
		if (!method.getName().startsWith("get"))
			return false;
		if (method.getParameterTypes().length != 0)
			return false;
		if (void.class.equals(method.getReturnType()))
			return false;
		return true;
	}

	private boolean isSetter(Method method) {
		if (!method.getName().startsWith("set"))
			return false;
		if (method.getParameterTypes().length != 1)
			return false;
		return true;
	}
	/**
	 * 测试访问私有成员变量和私有方法
	 */
	public void testPrivateFieldAndMethod(){
		Class<Student> studentClass = null;
		try {
			studentClass = (Class<Student>)Class.forName("edu.njupt.zhb.reflection.Student");
		} catch (ClassNotFoundException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}// 获得Class对象
		Student student = new Student("1012010638","郑海波");
		try {
			Field []privateFields = studentClass.getDeclaredFields();//获取私有方法
			for(Field field:privateFields){
				field.setAccessible(true);//设置可访问权限
				String fieldValue = ""+field.get(student);
				String fieldName = field.getName();
				System.out.println(fieldName+":"+fieldValue);
			}
			System.out.println("**获取私有方法----------");
			Method method = studentClass.getDeclaredMethod("privateMethod",null);
			method.setAccessible(true);
			method.invoke(student, null);
		} catch (SecurityException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

4.输出结果

--基本信息的输出----------------------------------------------------------------
className=edu.njupt.zhb.reflection.Student
field=public boolean edu.njupt.zhb.reflection.Student.isGood
method=public java.lang.String edu.njupt.zhb.reflection.Student.getName()
method=public java.lang.String edu.njupt.zhb.reflection.Student.getId()
method=public void edu.njupt.zhb.reflection.Student.setName(java.lang.String)
method=public void edu.njupt.zhb.reflection.Student.say()
method=public void edu.njupt.zhb.reflection.Student.setId(java.lang.String)
method=public final void java.lang.Object.wait() throws java.lang.InterruptedException
method=public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method=public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
method=public native int java.lang.Object.hashCode()
method=public final native java.lang.Class java.lang.Object.getClass()
method=public boolean java.lang.Object.equals(java.lang.Object)
method=public java.lang.String java.lang.Object.toString()
method=public final native void java.lang.Object.notify()
method=public final native void java.lang.Object.notifyAll()
false
packagePath=edu.njupt.zhb.reflection
superclassName=java.lang.Object
interfaceName=edu.njupt.zhb.reflection.Person
constructor=public edu.njupt.zhb.reflection.Student()
constructor=public edu.njupt.zhb.reflection.Student(java.lang.String,java.lang.String)
annotation=@java.lang.Deprecated()
--测试构造方法的输出----------------------------------------------------------------
I am a student,My name is 郑海波,My id is 1012010638
--测试invoke方法的输出----------------------------------------------------------------
I am a student,My name is 郑海波,My id is 1012010638
id = 1012010638
I am a student,My name is 郑海波,My id is B08020526
--测试获取get和set方法的输出----------------------------------------------------------------
getter: public java.lang.String edu.njupt.zhb.reflection.Student.getName()
getter: public java.lang.String edu.njupt.zhb.reflection.Student.getId()
setter: public void edu.njupt.zhb.reflection.Student.setName(java.lang.String)
setter: public void edu.njupt.zhb.reflection.Student.setId(java.lang.String)
getter: public final native java.lang.Class java.lang.Object.getClass()
--测试访问私有成员变量和私有函数的输出--------------------------------------------------------
isGood:false
id:1012010638
name:郑海波
**获取私有方法----------
this is a private Method!

下一步将说说Java设计模式之动态代理

未经允许不得用于商业目的


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值