java反射

Java反射涉及的几个类分别为Class,Filed,Methods,Constructor,Modifier,AccessibleObject的几个类。java

咱们定义一个 Employee类web

package util;

import java.util.Date;
import java.util.GregorianCalendar;

public class Employee {
	private String name;
	private double salary;
	private Date hireDay;

	public Employee(String n, double s, int year, int month, int day) {
		name = n;
		salary = s;
		GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
		hireDay = calendar.getTime();
	}

	public String getName() {
		return name;
	}

	public double getSalary() {
		return salary;
	}

	public Date getHireDay() {
		return hireDay;
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}
}

Employee为一个类,而代码apache

Employee harry=new Employee("Harry Hacker",3500,10,1,1989);

定义了一个 对象harry, 类Employee用来描述 对象harry的信息,而Java虚拟机在运行的时候须要一个类来描述 类Employee的信息,这个类就是 Class,称之为 类型,能够用来获取一个类的全部域 Field,构造器 Constructor,方法 Method。 反射的两个很重要的两个能力。分析一个类和执行任意方法。数组

分析一个类

package util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

import org.apache.commons.lang3.StringUtils;

public class ReflectionTest {
	public static void main(String[] args) {
		String name;
		if (args.length > 0) {
			name = args[0];
		} else {
			Scanner scanner = new Scanner(System.in);
			name = scanner.nextLine();
		}

		try {
			Class cl = Class.forName(name);
			Class supercl = cl.getSuperclass();
			String modifier = Modifier.toString(cl.getModifiers());
			if (modifier != null && modifier.length() > 0) {
				System.out.print(modifier + " ");
			}
			System.out.print("class " + name);
			Double aDouble = 0.0;
			if (supercl != null && supercl != Object.class) {
				System.out.print(" extends " + supercl.getName());
			}
			System.out.print("\n{\n");
			printConstructors(cl);
			printMethods(cl);
			printFields(cl);
			System.out.print("}\n");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//打印构造函数
	public static void printConstructors(Class cl) {
		Constructor[] constructors = cl.getDeclaredConstructors();
		for (Constructor constructor : constructors) {
			String name = constructor.getName();
			String modifier = Modifier.toString(constructor.getModifiers());
			System.out.print(" ");
			// System.out.print(modifier+" "+name+"(");
			if (modifier!=null&&modifier.length()>0) {
				System.out.print(modifier+" ");
			}
			System.out.print(name+" (");
			Class[] paraTypes=constructor.getParameterTypes();
			for(int i=0;i<paraTypes.length;i++){
				if (i>0) {
					System.out.print(",");
				}
				System.out.print(paraTypes[i].getName());
			}
			System.out.println(");");

		}
	}
	
	//打印成员变量
	public static void printFields(Class cl){
		
		Field[] fields=cl.getDeclaredFields();
		for (Field field : fields) {
			String modifier=Modifier.toString(field.getModifiers());
			Class type=field.getType();
			String name=field.getName();
			System.out.print(" ");
			if (modifier.length()>0) {
				System.out.print(modifier+"  ");
			}
			System.out.println(type.getName()+"  "+name+";");
		}
		
	}
	
	//打印方法名
	public static void printMethods(Class cl){
		 Method[] methods=cl.getDeclaredMethods();
		 for (Method method : methods) {
			 String name=method.getName();
			 String modifier=Modifier.toString(method.getModifiers());
			 System.out.print(" ");
			 if (modifier.length()>0) {
				System.out.print(modifier+" ");
			}
			 System.out.print(method.getName()+"(");
			 Class[] paraTypes=method.getParameterTypes();
			 for(int i=0;i<paraTypes.length;i++){
				 if (i>0) {
					System.out.print(",");
				}
				 System.out.print(method.getName());
			 }
			 System.out.println("};");
		}
	}
}

执行任意方法

package study_web;

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

public class MethodTest {
	public static void main(String[] args) {
		/*System.out.println(Math.sqrt(4));*/
		try {
			Class cl=Class.forName("java.lang.Math");
			try {
				Method method=cl.getDeclaredMethod("sqrt", double.class);
				/*Class returnType=method.getReturnType();*/
				Double value=(Double) method.invoke(null, 4.0);
				System.out.println(value);
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

在这个demo中咱们用反射执行了Math.sqrt方法函数

获取一个域,并从新赋值

package study_web;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;

import util.Employee;

public class ReflectTest {
	public static void main(String[] args) {
		Employee harry=new Employee("Harry Hacker",3500,10,1,1989);
		Class cl=harry.getClass();
		try {
			Field field=cl.getDeclaredField("name");
			/*AccessibleObject[] array=new AccessibleObject[]{field};
			AccessibleObject.setAccessible(array, true);*/
			field.setAccessible(true);
			field.set(harry, "li yuahng");
			System.out.println(harry.getName());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

由于Java反射默认听从Java访问权限控制,因此咱们能够使用代码:code

AccessibleObject[] array=new AccessibleObject[]{field};
	    AccessibleObject.setAccessible(array, true);

或者代码:对象

field.setAccessible(true);

使得Field域可被访问。继承

一些重要的API

java.lang.Class

  • public static Class<?> forName(String className)

返回描述类名className的Class对象接口

  • public T newInstance()

返回这个类的新实例字符串

  • public Field[] getFields()
  • public Field[] getDeclaredFields()

getFields方法返回一个包含Field对象的数组,这些对象记录了这个类或其它超类的公有域。getDeclaredFields方法也将返回包含Field对象的数组,这些对象记录了这个类的所有域。若是类中没有域,或者Class对象描述的是基本类型或者数据类型,这些方法将返回一个长度为0的数组

  • public Method[] getMethods()
  • public Method[] getDeclaredMethods()

返回包含 Method对象的数组:getMethods将返回全部的公有方法,包括从超类继承来的公有方法;getDeclaredMethods返回这个类或接口的的所有方法,但不包括由超类继承来的方法。

  • public Constructor<?>[] getDeclaredConstructors()
  • public Constructor<?>[] getConstructors()

同上,不作解释

  • public native int getModifiers()

返回一个用于描述构造器、方法、域的修饰符的整型数值。使用Modifier类中的这个方法能够分析这个返回值。

###java.lang.reflect.Modifier

  • public static String toString(int mod)

返回modifiers中位设置的修饰符的字符串表示

java.lang.reflect.AccessibleObject

  • public void setAccessible(boolean flag)

为反射对象设置可访问标志。flag为true,代表屏蔽Java语言的访问检查,使得对象的私有属性也能够被查询和设置

  • public boolean isAccessible()

返回反射对象可访问标志的值

  • public static void setAccessible(AccessibleObject[] array, boolean flag)

是一种设置对象数组可访问标志的快捷方法

java.lang.reflect.Field

  • public void set(Object obj, Object value)

用一个新值设置obj对象中Field对象表示的域

java.lang.reflect.Method

  • public Object invoke(Object obj, Object... args)

对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

相关文章
相关标签/搜索