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); } }