反射

  • 框架设计的灵魂

获取class对象方式

  1. Class.forName(“包名.类名”)
    • 将字节码文件加载进内存,返回类对象(class对象)
    • 多用于配置文件
  2. 类名.class
    • 多用于参数传递
  3. 对象.getClass()

同一个字节码文件(*.class)在一次程序运行中,只会加载一次。
无论通过哪种方式获取class对象都是同一个

Class对象

  • 封装了 成员变量,构造方法,成员方法

Class的常用方法

获取成员变量

返回类型 方法 描述
Field[] getFields() 所有public成员变量
Field getField(String name) 指定public成员变量
Field[] getDeclaredFields() 所有成员变量
Field getDeclaredField(String name) 指定成员变量
  • java.lang.reflect.Field的方法

    • get

      Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。
      String getName() 获取成员的变量的名字
    • set

      void set(Object obj, Object value) 设置为指定的新值。

      成员.setAccessible(true); //忽略该成员访问权限修饰符的安全检查

获取构造方法

返回类型
Constructor getConstructor(Class... parameterTypes)
Constructor[] getConstructors()
Constructor getDeclaredConstructor(Class... parameterTypes)
Constructor[] getDeclaredConstructors()
Constructor<?> getEnclosingConstructor()
  • java.lang.reflect.Constructor 方法

    T newInstance(参数) 创建该构造方法的声明类的新实例

获取成员方法

Method getMethod(String , Class... parameterTypes)
Method[] getMethods()
Method getDeclaredMethod(String name, Class... parameterTypes)
Method[] getDeclaredMethods()
  • java.lang.reflect.Method方法

    Object invoke(Object obj, Object... args) 执行成员方法
    String getName() 获取成员方法名

获取类名,包名

String getName() Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称
Package getPackage() 获取此类的包。

源码

  1. fashe.java
package test_03;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

public class fashe {

	private static Method[] declaredMethods;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		
		student st = new student();
		/*
		 * 获取类对象的三种方式(1,2,3)
		 * 	1. 类.class
		 *  2. Class.forName("包名.类名")
		 *  3. 对象.getClass()
		 */
		System.out.println("----------获取Class对象的三种方式------");

		Class clazz1 = student.class;	
		Class clazz2 = Class.forName("test_03.student");
		Class clazz3 = st.getClass();
		System.out.println( clazz3 );
		
		/*
		 * 获取成员变量
		 * 		1. 获取共有(public)成员变量:getFields() , getField("成员变量名")
		 * 		2. 获取所有成员变量:getDeclaredFields() , getDeclaredField("成员变量名")
		 */
		System.out.println("\n----------获取成员变量------");
		Field[] fields = clazz2.getDeclaredFields();
		
		for (Field field : fields) {
			System.out.println( field );
		}
		Field name = clazz1.getDeclaredField("name");

		
		
		//忽略该成员访问权限修饰符的安全检查
		name.setAccessible(true);
		
		/*
		 * Field方法(get,set)
		 * 
		 * get( 对象 ) :  获取public成员变量的值(忽略访问权限修饰符的安全检查后,后获取私有的成员变量值)
		 * set(属性对象,值 ) : 设置指定成员的值
		 * 
		 */
		System.out.println("\n----------get、set-----");
		System.out.println( name.get( st ) );
		name.set(st, "罗伊人");
		System.out.println( name.get( st ) );
		System.out.println( name.getName()  );	//获取成员的变量的名字
		
		/*
		 * 获取构造方法
		 * 1. getConstructor( class ...args )
		 * 2. getConstructors()
		 */
		System.out.println(  "\n----------获取构造方法------------" );
		Constructor[] constructors = clazz1.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println( constructor );
		}
		
		Constructor<student> constructor1 = clazz2.getConstructor( null );
		Constructor<student> constructor2 = clazz2.getConstructor( int.class , String.class );
		System.out.println( constructor1  );
		System.out.println( constructor2  );
		
		/*
		 * Constructor的方法
		 * 1. newInstance(参数)  创建对象
		 * 2. class对象.newInstance() 创建空参对象
		 * 3. class对象.getConstructor(null).newInstance()  创建空参对象
		 */
		System.out.println( "\n----------创建对象-----------" );
		student st2 = constructor2.newInstance(3,"江莱");
		System.out.println( st2 );
		
		Object newInstance = clazz3.newInstance();//class对象中的空参数对象构造方法
		System.out.println( newInstance );
		
		/*
		 * 获取成员方法
		 * 1. getMethods		获取所有的共有的(public)方法
		 * 2. 
		 */
		System.out.println( "\n------------获取成员方法-----------------" );	
		
		Method[] methods = clazz2.getMethods();
		for (Method method : methods) {
			System.out.println( method );
		}
		System.out.println("\n");
		Method[] declaredMethods = clazz1.getDeclaredMethods();
		for (Method method : declaredMethods) {
			System.out.println(method );
		}
		
		Method tsg = clazz1.getMethod("toString", null);
		/*
		 * 执行成员方法(java.lang.reflect.Method)
		 *  1. Object invoke(Object obj, Object... args)  	执行成员方法
		 *  2. String getName()								获取成员方法名
		 */
		System.out.println("\n--------- 执行成员方法---------");
		System.out.println( tsg );
		System.out.println( tsg.invoke(st2) );
		System.out.println( tsg.getName()  );
		
		System.out.println( st );
		clazz2.getMethod("setAge", int.class).invoke(st, 24);
		System.out.println( st );
		
		/*
		 * 获取类名
		 * 1. String getName()	
		 */
		System.out.println( "\n----------获取类名------------" );
		System.out.println( clazz1.getName() );
		
		
		System.out.println( "\n----------案例--------" );
		
		createObj();
		
	}
	
	/*
	 * 案例- 任意对象的创建
	 */
	
	public static void createObj(  ) throws Exception {
		//加载配置文件
		Properties pros = new Properties();
		InputStream is = fashe.class.getClassLoader().getResourceAsStream("pro.properties");
		pros.load(is);
		
		//获取配置文件信息
		
		String className = pros.getProperty("className");
		String method = pros.getProperty("methodName");
		
		//加载该类进内存
		Class<?> clazz = Class.forName(className);
		
		//创建对象
		Object obj = clazz.newInstance();
		
		//获取方法对象
		Method method2 = clazz.getMethod(method);
		
		//执行方法
		System.out.println( method2.invoke(obj)  );
		
	}
	
}
  1. pro.properties
className=test_03.student
methodName=toString
  1. studnet.java
package test_03;


public class student{
	private int age ;
	private String name;
	public student(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "student [age=" + age + ", name=" + name + "]";
	}
	public student() {
		super();
	}
	private void pt() {
		
	}
	
}
posted @ 2020-03-01 15:21  Tolbert  阅读(80)  评论(0)    收藏  举报