zoukankan      html  css  js  c++  java
  • 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(" { "); printFields(_sb, _class); _sb.append(" "); printConstructors(_sb, _class); _sb.append(" "); printMethods(_sb, _class); _sb.append("} "); 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("; ")); } } /** * 打印这个类的所有构造方法 **/ 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("); "); } } /** * 打印这个类的所有非构造方法 **/ 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("); "); } } }

     输出结果如下:

     

    第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){
            }
        }
    }
  • 相关阅读:
    《重构》读书笔记
    每周总结
    《修改代码的艺术》读书笔记
    每周总结
    每周总结
    《修改代码的艺术》读书笔记
    每周总结
    第二周周总结
    以淘宝网为例,描绘质量属性的六个常见属性场景
    机器学习第八讲
  • 原文地址:https://www.cnblogs.com/bravestarrhu/p/reflect.html
Copyright © 2011-2022 走看看