java_反射_及其简单应用(2016-11-16)

话不多说直接上代码

 

接口:

package bean;

/**
 * user接口
 */
public interface User {
	
	public String getName();
	
	public void setName(String name);

}

父类:

package bean;

/**
 * 人 作为userImpl的父类
 */
public class Person {
	private String name;

	public String city;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", city=" + city + "]";
	}

}

实现类:

package bean;

/**
 * 用户实现类
 * 当前类没有实现user中的方法,由父类中实现。
 */
public class UserImpl extends Person implements User{
	
	/**
	 * 用户名
	 */
	private String userName;
	
	/**
	 * 密码
	 */
	private String Password;
	
	/**
	 * 是否富有
	 */
	boolean isRich;

	/**
	 * 年龄
	 */
	protected int age;
	
	/**
	 * 信息
	 */
	public StringBuffer info;
	
	public UserImpl() {
		super();
	}

	public UserImpl(String userName) {
		super();
		this.userName = userName;
	}


	@Override
	public String toString() {
		return "UserImpl [userName=" + userName + ", Password=" + Password
				+ ", isRich=" + isRich + ", age=" + age + ", info=" + info
				+ "]";
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPassword() {
		return Password;
	}

	public void setPassword(String password) {
		Password = password;
	}

	public boolean isRich() {
		return isRich;
	}

	public void setRich(boolean isRich) {
		this.isRich = isRich;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public StringBuffer getInfo() {
		return info;
	}

	public void setInfo(StringBuffer info) {
		this.info = info;
	}
}

工厂接口:

package bean;

public interface Factory {
	
	<T> T getBean(String name, Class<T> requiredType) throws Exception;
}

工厂:

package bean;

public class FactoryImpl  implements Factory{

	/**
	 * 获取实例
	 * @param class1
	 * @return
	 * @throws Exception 
	 */
	@SuppressWarnings("unchecked")
	@Override
	public  <T> T getBean(String name, Class<T> requiredType) throws Exception {
		Object object = null;
		try {
			Class<?> clazz = Class.forName(name);
			object = clazz.newInstance();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		//如果obj是这个类的一个实例此方法返回true。
		if (requiredType != null && !requiredType.isInstance(object)) {
			throw new Exception("类不同,抛异常");
		}
		return (T)object;
	}

}

测试类:

package bean;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class ReflectTest {

	private String className = "bean.UserImpl";
	
	/**
	 * 获取实例化Class类对象
	 */
	@Test
	public void test01() throws ClassNotFoundException {

		Class<?> class1 = null;
		Class<?> class2 = null;
		Class<?> class3 = null;

		// 第一种方式:
		class1 = Class.forName(className);// 一般采用这种形式
		// 第二种方式:java中每个类型都有class 属性.
		class2 = UserImpl.class;
		// 第三种方式: java语言中任何一个java对象都有getClass 方法
		class3 = new UserImpl().getClass();

		System.out.println("类名称   " + class1.getName());
		System.out.println("类名称   " + class2.getName());
		System.out.println("类名称   " + class3.getName());
		
		//?号的用法。
		//T就是将类型固定,而?则不固定
		//List<?> userList = new ArrayList<>();
	}
	
	/**
	 * 获取类以后我们来创建它的对象
	 */
	@Test
	public void test02() throws ClassNotFoundException, InstantiationException, IllegalAccessException  {

		Class<?> clazz = Class.forName(className);

		// 创建此Class 对象所表示的类的一个新实例
		Object object = clazz.newInstance(); // 调用无参数构造方法.

		System.out.println(clazz);
		System.out.println(object);
	}
	
	/**
	 * 获取对象继承的父类以及实现接口
	 * @throws ClassNotFoundException 
	 */
	@Test
	public void test03() throws ClassNotFoundException  {
		
		Class<?> clazz = Class.forName(className);

		// 直接父类
		Class<?> superclass = clazz.getSuperclass();
		System.out.println("clazz的直接父类为:" + superclass.getName());//calzz的父类为:bean.Person

		// 所有的接口
		Class<?>[] interfaces = clazz.getInterfaces();
		System.out.println("clazz实现的接口有:");
		for (int i = 0; i < interfaces.length; i++) {
			System.out.println((i + 1) + ":" + interfaces[i].getName());
		}
		// clazz实现的接口有:
		// 1:bean.User
		
	}
	
	/**
	 * 获取某个类的全部属性
	 * @throws ClassNotFoundException 
	 */
	@Test
	public void test04() throws ClassNotFoundException  {
		Class<?> clazz = Class.forName(className);
		
		System.out.println("=============== 当前类属性 field ===============");
		
		// 取得本类的全部属性
		Field[] declaredFields = clazz.getDeclaredFields();
		for (Field field : declaredFields) {
			// 权限修饰符
			int modifiers = field.getModifiers();
			String priv = Modifier.toString(modifiers);
			// 属性类型
			Class<?> type = field.getType();
		    System.out.println(priv + " " + type.getName() + " " + field.getName() + ";");
		}
		
		System.out.println("=============== 实现的接口或者父类的属性 field ==========");
		System.out.println("=============== 当前类及其父类或接口的public类型属性 ==========");

        // 取得实现的接口或者父类的属性
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
        	// 权限修饰符
			int modifiers = field.getModifiers();
			String priv = Modifier.toString(modifiers);
			// 属性类型
			Class<?> type = field.getType();
		    System.out.println(priv + " " + type.getName() + " " + field.getName() + ";");
		}
        
	}
	
	/**
	 * 获取某个类的全部方法
	 * @throws ClassNotFoundException 
	 */
	@Test
	public void test05() throws ClassNotFoundException  {

		Class<?> clazz = Class.forName(className);

		System.out.println("=============== 当前类能调用的所有方法 ===============");
		
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			Class<?> returnType = method.getReturnType();
			Class<?>[] parameterTypes = method.getParameterTypes();
			Class<?>[] exceptionTypes = method.getExceptionTypes();
			int modifiers = method.getModifiers();
			String priv = Modifier.toString(modifiers);

			StringBuffer content = new StringBuffer();
			content.append(priv + " " + returnType.getName() + " " + method.getName() + "( ");
			//方法参数类型集合
			if (null != parameterTypes && parameterTypes.length > 0) {
				for (Class<?> parameterType : parameterTypes) {
					content.append(parameterType.getName() + " " + ",");
				}
				content.delete(content.length() - 1, content.length());
			}
			content.append(" )");
			// 方法抛出的异常
			if (null != exceptionTypes && exceptionTypes.length > 0) {
				content.append(" throws ");
				for (Class<?> exceptionType : exceptionTypes) {
					content.append(exceptionType.getName() + " " + ",");
				}
				content.delete(content.length() - 1, content.length());
			}
		    System.out.println(content);
		}
	}
	
	/**
	 * 通过反射机制调用某个类的方法
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 */
	@Test
	public void test06()  throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException  {

		Class<?> clazz = Class.forName(className);

		System.out.println("=============== Java 反射机制 - 调用某个类的方法toString ===============");
		Object obj = clazz.newInstance();
		
		//调用userImpl的setUserName方法。前提:实例
		Method method = clazz.getMethod("setUserName",String.class);
		Object result = method.invoke(obj,"张三");
		System.out.println("Java 反射机制 - 调用某个类的方法setUserName:" + result);

		//调用userImpl的toString方法。前提:实例
		Method method2 = clazz.getMethod("toString");
		Object result2 = method2.invoke(obj);
		System.out.println("Java 反射机制 - 调用某个类的方法toString:" + result2);
	}
	
	/**
	 * 通过反射机制操作某个类的属性
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	@Test
	public void test07() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException  {
		Class<?> clazz = Class.forName(className);

		System.out.println("=============== Java 反射机制 - 操作某个类的属性 ===============");
		Object obj = clazz.newInstance();
		Field declaredField = clazz.getDeclaredField("userName");
		// 可以直接对 private 的属性赋值
		//java.lang.IllegalAccessException: Class bean.ReflectTest can not access a member of class bean.UserImpl with modifiers "private"
		declaredField.setAccessible(true);
		declaredField.set(obj, "Java反射机制");
		System.out.println(declaredField.get(obj));
		System.out.println(obj);
	}
	
	/**
	 * 获取构造函数  
	 */
	@Test
	public void test08() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> clazz = Class.forName(className);

		System.out.println("=============== Java 反射机制 - 获取构造函数   ===============");
		
		Constructor<?>[] constructors = clazz.getConstructors();
		if(null != constructors && constructors.length >0){
			for (Constructor<?> constructor : constructors) {
				System.out.println("构造方法:  "+ constructor);  
			}
			Object user1 = constructors[0].newInstance();
			Object user2 = constructors[1].newInstance("用户名啊");
			System.out.println(user1);
			System.out.println(user2);
		}

	}
	
	/**
	 * 调用set和get方法 
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	@Test
	public void test09() throws ClassNotFoundException, InstantiationException, IllegalAccessException  {
		Class<?> clazz = Class.forName(className);
		
		System.out.println("=============== Java 反射机制 - 调用set和get方法    ===============");
		Object obj = clazz.newInstance();
		setter(obj, "userName", String.class, "名字呢");
		System.out.println("set后的对象:"+obj);

		Object result = getter(obj, "userName");
		System.out.println("get得到的内容:" + result);

	}
	
	/**
	 * 通过反射取得并修改数组的信息
	 */
	@Test
	public void test10()  {
		int[] temps = { 1, 2, 3, 4, 5 };
		System.out.println("=============== Java 反射机制 - 取得并修改数组的信息 ===============");

		// 获得数组内部类型
		Class<?> componentType = temps.getClass().getComponentType();
		
		System.out.println("数组类型: " + componentType.getName());
		System.out.println("数组长度:  " + Array.getLength(temps));
		System.out.println("数组的第一个元素: " + Array.get(temps, 0));
		Array.set(temps, 0, 100);
		System.out.println("修改之后数组第一个元素为: " + Array.get(temps, 0));
	}
	
	
	
	/**
	 * 通过反射机制修改数组的大小
	 */
	@Test
	public void test11()  {
		System.out.println("=============== Java 反射机制 - 修改数组的大小 ===============");

		int[] temps = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int[] newTemps = (int[]) modifyArrayLength(temps, 15);
		printArray(newTemps);
		
		String[] atr = { "a", "b", "c" };
		String[] str1 = (String[]) modifyArrayLength(atr, 8);
		printArray(str1);
	}
	

	/**
	 * 在泛型为Integer的ArrayList中存放一个String类型的对象。
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	@Test
	public void test12() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException  {
		
		System.out.println("=============== Java 反射机制 - 在泛型为Integer的ArrayList中存放一个String类型的对象。===============");

		List<Integer> list = new ArrayList<Integer>();
		@SuppressWarnings("rawtypes")
		Class<? extends List> class1 = list.getClass();
		Method method = class1.getMethod("add", Object.class);
		method.invoke(list, "这是:String类型的对象");
		System.out.println(list);
		
	}
	
	/**
	 * 将反射机制应用于工厂模式
	 * 模仿一下spring
	 * @throws Exception 
	 */
	@Test
	public void test13() throws Exception  {
		System.out.println("=============== Java 反射机制 - 将反射机制应用于工厂模式 ===============");
		FactoryImpl factory = new FactoryImpl();
		UserImpl user = factory.getBean(className,UserImpl.class);
		System.out.println(user);
	}
	
	
	
	/**
	 * 反射机制的动态代理
	 */
	@Test
	public void test14()  {
		System.out.println("=============== Java 反射机制 - 反射机制的动态代理===============");
		MyInvocationHandler demo = new MyInvocationHandler();
		UserImpl userImpl = new UserImpl();
		User user = (User) demo.bind(userImpl);
        user.setName("Rollen");
        System.out.println(user);
	}
	
	
	/**
	 * 内部类
	 * 实现调用处理接口
	 * @author chenchuan
	 *
	 */
	class MyInvocationHandler implements InvocationHandler {
	    private Object obj = null;
	    public Object bind(Object obj) {
	        this.obj = obj;
	        ClassLoader classLoader = obj.getClass().getClassLoader();
	        Class<?>[] interfaces = obj.getClass().getInterfaces();//目标类的父类及即接口,可以发现执行目标方法时,先执行父类或接口对应的方法
	        return Proxy.newProxyInstance(classLoader,interfaces , this);
	    }
	    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	    	System.out.println("目标方法(" + method +")开始前...");
	        Object temp = method.invoke(this.obj, args);
	        System.out.println("目标方法(" + method+")结束后...");
	        return temp;
	    }
	}

	/**
	 *  打印
	 * @param obj
	 */
    public static void printArray(Object obj) {
		Class<?> c = obj.getClass();
		if (!c.isArray()) {
			return;
		}
		System.out.println("数组长度为: " + Array.getLength(obj));
		for (int i = 0; i < Array.getLength(obj); i++) {
			System.out.print(Array.get(obj, i) + " ");
		}
		System.out.println();
    }
    
	/**
	 * 修改数组大小
	 * @param obj
	 * @param newLength
	 * @return
	 */
    public  Object modifyArrayLength(Object obj, int newLength) {
    	Class<?> componentType = obj.getClass().getComponentType();
        Object newArray = Array.newInstance(componentType, newLength);
        int co = Array.getLength(obj);
        System.arraycopy(obj, 0, newArray, 0, co);
        return newArray;
    }

	/**
	 * 
	 * 执行get方法
	 * @param obj 操作的对象
	 * @param fieldName操作的属性
	 */
	public  Object getter(Object obj, String fieldName) {
		
		StringBuffer methodName = new StringBuffer();
		methodName.append("get");
//		sb.append(fieldName.substring(0, 1).toUpperCase());
//		sb.append(fieldName.substring(1));
		methodName.append(getMethodName(fieldName));
		
		Object invoke = null;
		try {
			Method method = obj.getClass().getMethod(methodName.toString());
			invoke = method.invoke(obj, new Object[0]);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return invoke;
	}
	
	/**
	 * @param obj
	 *            操作的对象
	 * @param fieldName
	 *            操作的属性
	 * @param type
	 *            参数的属性
	 * @param value
	 *            设置的值
	 * */
	public  void setter(Object obj, String fieldName, Class<?> type, Object... value) {
		
		StringBuffer methodName = new StringBuffer();
		methodName.append("set");
//		sb.append(fieldName.substring(0, 1).toUpperCase());
//		sb.append(fieldName.substring(1));
		methodName.append(getMethodName(fieldName));
		
		try {
			Method method = obj.getClass().getMethod(methodName.toString(), type);
			method.invoke(obj, value);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	} 
	
	/**
	 * 把一个字符串的第一个字母大写、效率是最高的、  
	 * @param fildeName
	 * @return
	 */
    private  String getMethodName(String fildeName) {  
        byte[] items = fildeName.getBytes();  
        items[0] = (byte) ((char) items[0] - 'a' + 'A');  
        return new String(items);  
    }  

}

  

posted @ 2016-11-16 17:53  scevecn  阅读(221)  评论(0编辑  收藏  举报