反射

反射

1. 反射
1.1 获取Method对象
1.1.1 一个成员方法你所关注的点
通过正常的途径调用一个成员方法:
	权限修饰符 [静态/abstract/final] 返回值类型 方法名(形式参数列表)
	
调用方法:
	类对象.方法名(实际参数);
	类名.方法名(实际参数);

方法的重载:
	1. 在同一个类内,或者接口内
	2. 要求方法名必须一致
	3. 要求当前方法的形式参数列表数据类型,个数,顺序必须不一致。

对于一个方法而言:
	1. 方法名
	2. 形式参数列表
1.1.2 Method涉及到的方法
Method[] getMethods();
	获取类内所有非私有化成员方法对象数组,包括从父类继承而来子类可以使用的成员方
	法。
	
Method[] getDeclaredMethods();
	获取类内所有成员方法对象数组,有且只有当前类内的特有方法,不包括父类继承给子类
	使用的方法,同时可以获取私有化方法。
	
Method getMethod(String methodName, Class... parameterTypes);
	根据指定的方法名,和对应的参数类型来获取指定的非私有化成员方法类对象
	案例:
		无参数方法 public void game();
		cls.getMethod("game");
		有参数方法 public void game(String);
		cls.getMethod("game", String.class);
		
Method getDeclaredMethod(String methodName, Class... parameterTypes);
	根据指定的方法名,和对应的参数类型获取类内的任意成员方法,包括私有化成员方法,
	不包括从父类继承而来的方法。
	案例:
		有参数私有化方法 private void testPrivate(String);
		cls.getDeclaredMethod("testPrivate", String.class);

Object invoke(Object obj, Object... parameters);
	Object obj 是执行当前方法的对象。
	Object... parameters 当前方法执行所需实际参数,为不定长参数
	Method类对象调用,传入执行当前方法的对象和对应当前方法的实际参数,执行当前方法。
package com.qfedu.a_reflect;

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

/*
 * 操作Method类对象
 */
public class GetMethodObject {
	public static void main(String[] args) 
			throws ClassNotFoundException, NoSuchMethodException, SecurityException, 
			InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		/*
		 * 通过完整的包名.类名获取对应的Class对象
		 */
		Class cls1 = Class.forName("com.qfedu.a_reflect.Person");
		
		Method[] methods = cls1.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		
		System.out.println();
		Method[] declaredMethods = cls1.getDeclaredMethods();
		for (Method method : declaredMethods) {
			System.out.println(method);
		}
		
		System.out.println();
		Method game1 = cls1.getMethod("game");
		Method game2 = cls1.getMethod("game", String.class);
		System.out.println(game1);
		System.out.println(game2);
		
		System.out.println();
		Method private1 = cls1.getDeclaredMethod("testPrivate");
		Method private2 = cls1.getDeclaredMethod("testPrivate", String.class);
		System.out.println(private1);
		System.out.println(private2);
		
		System.out.println();
		
		Object object = cls1.getConstructor().newInstance();
		game1.invoke(object);
		game2.invoke(object, "我的世界");
		
		// 给予暴力反射对象操作权限。。。
		private1.setAccessible(true);
		private2.setAccessible(true);
		
		private1.invoke(object);
		private2.invoke(object, "韭菜猪肉");
	}
}
1.2 获取Field对象
1.2.1 成员变量你关注什么???
关注内容:
	权限修饰符 [static/fianl] 数据类型 名字

成员变量的唯一性:
	成员变量名字
	在成员变量对象Field中,可以获取当前成员变量数据类型,权限修饰符标记,关键字修饰标记
	
原本:
	类对象.set成员变量名(数据);
	类对象.get成员变量名();
1.2.2 Field涉及到的方法
Field[] getFields();
	获取当前类内所有非私有化成员变量类对象数组
Field[] getDeclaredFields();
	获取当前类内所有成员变量类对象数组,包括私有化成员变量
Field getField(String fieldName);
	根据指定的成员变量名字获取对应的非私有化成员变量类对象
Field getDeclaredField(String fieldName);
	根据指定的成员变量名字获取对应的成员变量类对象,包括私有化成员变量类对象。
	
void set(Object obj, Object value);
	Object obj 哪一个对象的成员变量
	Object value 对应当前成员变量的数据
	通过Field类对象调用,传入参数是当前操作的哪一个类对象明确说明和对应的赋值数据
Object get(Object obj);
	Object obj 明确哪一个对象的成员变量
	通过Field类对象调用,获取指定对象的对应成员变量数据,返回值是对应成员变量数据内容为Object类型

补充方法:
	String getName();
	Class getType();
1.3 反射案例实现
package com.qfedu.b;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

import javax.accessibility.Accessible;

public class Demo1 {
	public static void main(String[] args) 
			throws FileNotFoundException, IOException, ClassNotFoundException, 
			InstantiationException, IllegalAccessException, IllegalArgumentException, 
			InvocationTargetException, NoSuchMethodException, SecurityException {
		// 属性类!!!
		Properties properties = new Properties();
		
		// 加载对应的文件
		properties.load(new FileInputStream("./src/worker.properties"));
		
		System.out.println(properties.getProperty("className"));
		System.out.println(properties.getProperty("id"));
		System.out.println(properties.getProperty("name"));
		System.out.println(properties.getProperty("gender"));
		
		System.out.println();
		String className = properties.getProperty("className");
		// 加载当前指定包名.类名对应的class
		Class<?> cls = Class.forName(className);
		
		// 根据配置文件对应的className创建对应的类对象
		Object obj = cls.getConstructor().newInstance();
		// 获取当前类内的所有成员变量
		Field[] declaredFields = cls.getDeclaredFields();
		// 给予所有私有化成员变量数组赋值操作权限
		AccessibleObject.setAccessible(declaredFields, true);
		
		// 所有的成员变量赋值操作!!!
		for (Field field : declaredFields) {
			// 赋值对应id成员变量
			if ("id".equals(field.getName())) {
				// id为int类型
				Class<?> type = field.getType();
				if (type == int.class) {
					field.set(obj, Integer.valueOf(properties.getProperty("id")));
				}
			}
			
			if ("name".equals(field.getName())) {
				field.set(obj, properties.getProperty("name"));
			}
			
			if ("gender".equals(field.getName())) {
				field.set(obj, properties.getProperty("gender").charAt(0));
			}
		}
		
		System.out.println(obj);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值