java中反射的使用
Posted alex_wongh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中反射的使用相关的知识,希望对你有一定的参考价值。
结合demo理解反射:
import java.lang.reflect.*; /** * 反射使用 **/ public class ReflectDemo{ public static void main(String[] args){ ReflectDemo demo = new ReflectDemo();
if(args.length == 0){
demo.showClassInfo(null);
}else{
demo.showClassInfo(args[0]);
} demo.getAndSetPrivateFieldValue(); demo.callPrivateMethod(); } private void showClassInfo(String className){ new showReflectionInfo().showClassInfo(className != null && className.length() > 0 ? className : "Test"); } /** * 利用反射获取并修改私有域的值 **/ private void getAndSetPrivateFieldValue(){ try{ // 利用反射创建实例 Class _testClass = Class.forName("Test");// Class.forName()方法获取Class对象 Object _t = _testClass.newInstance();// 使用Class对象.newInstance()创建对象实例 Field _f = Test.class.getDeclaredField("name"); _f.setAccessible(true);// 设置私有的域可被访问 Object _value = _f.get(_t); // 使用get(Object obj)方法获取私有域的值 System.out.println(_value);// 输出 zhangsan _f.set(_t, "wangwu");// 使用set(Object obj, Object newValue)方法修改私有域的值 _value = _f.get(_t); System.out.println(_value);// 输出 wangwu System.out.println(); }catch(Exception e){ e.printStackTrace(); } } /** * 利用反射调用其他类的私有方法 **/ private void callPrivateMethod(){ Test _t= new Test(); System.out.println(_t.getName()); //_t.setName("lisi");// setName为Test类的私有方法,外部不可以直接这样调用// 使用反射机制调用Test类的私有方法setName() Method _m = null; try{ // _m = Test.class.getDeclaredMethod("setName", String.class); /* 方法二:使用反射得到setName()方法 Class _cl = _t.getClass(); Method[] _ms = _cl.getDeclaredMethods(); for(int i=0;i<_ms.length;i++){ if(_ms[i].getName().equals("setName")){ _m = _ms[i]; break; } } */ _m.setAccessible(true);// 不设置可访问权限,会报错java.lang.IllegalAccessException: Class ReflectDemo can not access a member of class Test with modifiers "private" _m.invoke(_t, "lisi");// invoke表示调用setName()方法,这里m就是setName()方法 }catch(Exception e){ e.printStackTrace(); } System.out.println(_t.getName()); } } class Test{ private String name = "zhangsan"; public String getName(){ return name; } private void setName(String paramName){ name = paramName; } } class showReflectionInfo{ /** * 利用反射分析类的能力 **/ public void showClassInfo(String paramClassName){ if(paramClassName != null && paramClassName.length() > 0){ try{ StringBuilder _sb = new StringBuilder(""); Class _class = Class.forName(paramClassName); Class _superClass = _class.getSuperclass(); String _modifier = Modifier.toString(_class.getModifiers()); if(_modifier != null && _modifier.length() > 0){ _sb.append(_modifier.concat(" ")); } _sb.append("class ".concat(_class.getName())); if(_superClass != null && _superClass != Object.class){ _sb.append(" extends ".concat(_superClass.getName())); } _sb.append(" {\\n"); printFields(_sb, _class); _sb.append("\\n"); printConstructors(_sb, _class); _sb.append("\\n"); printMethods(_sb, _class); _sb.append("}\\n"); System.out.println(_sb.toString()); }catch(Exception e){ e.printStackTrace(); } } } /** * 打印这个类的所有域 **/ private void printFields(StringBuilder paramStringBuilder, Class paramClass){ if(paramStringBuilder == null || paramClass == null){ return; } // getDeclaredFields()返回这个类或接口的全部域(含私有域);getFields()返回本类/接口及其所有父类/接口的所有公有域 Field[] _fields = paramClass.getDeclaredFields(); String _modifier = ""; for(Field _f:_fields){ paramStringBuilder.append(" "); _modifier = Modifier.toString(_f.getModifiers()); if(_modifier != null && _modifier.length() > 0){ paramStringBuilder.append(_modifier.concat(" ")); } Class _type = _f.getType(); paramStringBuilder.append(_type.getName().concat(" ")); paramStringBuilder.append(_f.getName().concat(";\\n")); } } /** * 打印这个类的所有构造方法 **/ private void printConstructors(StringBuilder paramStringBuilder, Class paramClass){ if(paramStringBuilder == null || paramClass == null){ return; } // getDeclaredConstructors()返回这个类的全部构造方法(含私有的);getConstructors()返回这个类所有公有构造方法 Constructor[] _constructors = paramClass.getDeclaredConstructors(); String _modifier = ""; for(Constructor _c:_constructors){ paramStringBuilder.append(" "); _modifier = Modifier.toString(_c.getModifiers()); if(_modifier != null && _modifier.length() > 0){ paramStringBuilder.append(_modifier.concat(" ")); } paramStringBuilder.append(_c.getName().concat("(")); Class[] _paramTypes = _c.getParameterTypes(); int _len = _paramTypes.length; for(int i = 0;i< _len;i++){ paramStringBuilder.append(_paramTypes[i].getName()); if(i<_len - 1){ paramStringBuilder.append(","); } } paramStringBuilder.append(");\\n"); } } /** * 打印这个类的所有非构造方法 **/ private void printMethods(StringBuilder paramStringBuilder, Class paramClass){ if(paramStringBuilder == null || paramClass == null){ return; } // getDeclaredMethods()返回这个类或接口的全部方法(含私有方法);getMethods()返回本类/接口及其所有父类/接口的所有公有方法 Method[] _methods = paramClass.getDeclaredMethods(); String _modifier = ""; for(Method _m:_methods){ paramStringBuilder.append(" "); // Modifier中静态方法:Modifier.toString()、Modifier.isAbstract()、Modifier.isPublic()、Modifier.isPrivate()... _modifier = Modifier.toString(_m.getModifiers()); if(_modifier != null && _modifier.length() > 0){ paramStringBuilder.append(_modifier.concat(" ")); } paramStringBuilder.append(_m.getReturnType().getName().concat(" ").concat(_m.getName()).concat("(")); Class[] _paramTypes = _m.getParameterTypes(); int _len = _paramTypes.length; for(int i = 0;i< _len;i++){ paramStringBuilder.append(_paramTypes[i].getName()); if(i<_len - 1){ paramStringBuilder.append(","); } } paramStringBuilder.append(");\\n"); } } }
输出结果如下:
第2个例子:
import java.util.*; import java.nio.file.*; import java.nio.charset.*; import java.io.*; import java.lang.reflect.*; /** * 利用反射机制使用Scanner类中私有构造方法private Scanner(Path source, Charset charset)读取打印文件内容 **/ public class ReflectDemo1{ public static void main(String[] args){ try{ // ###### 获取构造函数Constructor对象 方法一:###### // 注意:使用getDeclaredConstructor()方法获取构造函数时声明处 Class<?> cl 切记一定要加<?> Class<?> cl = Class.forName("java.util.Scanner"); // 也可以Class<?> cl = Scanner.class; Constructor cons = cl.getDeclaredConstructor(Path.class,Charset.class); /* // ###### 获取构造函数Constructor对象 方法二:###### Class cl = Class.forName("java.util.Scanner"); Constructor cons = null; Constructor[] cts = cl.getDeclaredConstructors(); Class[] cls; for(Constructor ct:cts){ cls = ct.getParameterTypes(); List<String> ll = new ArrayList<String>(cls.length); for(Class c:cls){ ll.add(c.getName()); } if(ll.contains(Path.class.getName()) && ll.contains(Charset.class.getName()) ){ cons = ct; break; } } */ if(cons !=null){ System.out.println("find it"); cons.setAccessible(true);// 因为这个构造方法是私有的,需要设置权限 Scanner scanner = (Scanner) cons.newInstance(Paths.get("ReflectDemo1.java"),Charset.forName("utf-8")); String str = ""; while((str = scanner.nextLine())!=null){ System.out.println(str); } } }catch(Exception e){ } } }
以上是关于java中反射的使用的主要内容,如果未能解决你的问题,请参考以下文章
使用反射在外部JAR / CLASS上调用包含Hibernate事务的方法(Java EE)