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)

反射机制入门

反射机制入门

反射机制入门

为啥我的 Ray March 片段着色器反射纹理查找会减慢我的帧速率?

# Java 反射的使用