zoukankan      html  css  js  c++  java
  • java反射机制例子,反编译,以及通过读取配置文件降低耦合

    一般意义上,要利用Java的反射需要以下步骤

         (1)加载Class对象,这个一般有两种方式:Class cls1 = UserInfo.class  或

        Class cls2 = Class.forName("domain.UserInfo") 后者是利用包名+类名的方法。

         (2)反射出来Class之后干啥事呢?一个类不外乎构造函数、成员变量、成员函数。所以得到Class之后就可以干这三件事。

    A、关于构造函数,获得Constructor 有四种方法: 

      Constructor getConstructor(Class[] params) 

      Constructor[] getConstructors() 

      Constructor getDeclaredConstructor(Class[] params) 

      Constructor[] getDeclaredConstructors()  

    这四个函数,如果不传参数则是获得所有的构造函数,得到的是一个集合。如果传特定的参数,则是寻找这个特定的构造函数,不带Declared是获得公共的public,带了Declared是可以获得私有构造函数。 得到构造函数后就可以利用反射创建实例了:

        Constructor con1[] = cls1.getDeclaredConstructors();
             con1[1].setAccessible(true);
             Object obj1 = con1[1].newInstance(new Object[]{"tom"}); 如果直接调用clcs.newInstance()则是用默认的构造函数创建实例。

    B、关于成员变量,同样有四种方法:

    public Field getDeclaredField(String name)  获取任意指定名字的成员
    public Field[] getDeclaredFields()          获取所有的成员变量
    public Field getField(String name)          获取任意public成员变量
    public Field[] getFields()                  获取所有的public成员变量

    利用这种方式操作类里的私有成员变量,记得要setAccessible打开开关。如下:

    Field field = cls.getDeclaredField(cols_name);
    field.setAccessible(true); //打开javabean的访问权限
    field.set(resultObject, cols_value);

    C、关于成员函数,也有四种方法:

    public Method[] getMethods()    获取所有的共有方法的集合
    public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 ,参数1:方法名 参数2:参数类型集合  

    public Method[] getDeclaredMethods()  获取所有的方法
    public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

    //这边以反编译String类为例子,将反编译结果输入到文件。

    1.ReflectTest.java

      1 import java.io.File;
      2 import java.io.FileReader;
      3 import java.io.FileWriter;
      4 import java.lang.reflect.Constructor;
      5 import java.lang.reflect.Field;
      6 import java.lang.reflect.Method;
      7 import java.lang.reflect.Modifier;
      8 import java.util.Properties;
      9 
     10 /**
     11  * 
     12  */
     13 
     14 /**
     15  * @author NXF
     16  *
     17  */
     18 public class ReflectTest {
     19 
     20     /**
     21      * @param args
     22      */
     23     public static void main(String[] args) throws Exception {
     24         // TODO Auto-generated method stub
     25         //1.创建属性对象
     26         Properties p = new Properties();
     27 
     28         //2.创建流
     29         FileReader fr = new FileReader("./src/classInfo.properties");
     30 
     31         //3.加载
     32         p.load(fr);
     33 
     34         //4.关闭流
     35         fr.close();
     36 
     37         //通过key获取value
     38         String className = p.getProperty("className");
     39         //通过反射机制创建对象
     40         Class c = Class.forName(className);
     41 
     42         //创建对象
     43         Object o = c.newInstance();
     44         
     45         
     46         new ReflectTest().printClass(c);
     47         
     48         
     49     }
     50 
     51     public void printClass(Class c) throws Exception
     52     {
     53         StringBuffer sb = new StringBuffer();
     54 
     55         sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{
    ");
     56         sb.append(getFileds(c));
     57         sb.append(getConstructors(c));
     58         sb.append(getMethods(c));
     59         sb.append("}
    ");
     60         sb.append(getSuperClass(c));
     61         sb.append(getFiled(c));
     62         sb.append(getMethod(c));
     63         
     64         System.out.println(sb);
     65         FileWriter fw = new FileWriter(new File("./src/classInfo.txt"));
     66         fw.write(sb.toString());
     67         fw.close();
     68         
     69     }
     70     
     71     /**
     72      * 根据Class c对象获取所有属性
     73      * @param c
     74      * @return
     75      */
     76     public String getFileds(Class c) {
     77         //获取所有的属性?
     78         Field[] fs = c.getDeclaredFields();
     79 
     80         StringBuffer sb = new StringBuffer();
     81 
     82         //sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{
    ");
     83         sb.append("///////////////////////////////////////the Fileds of Class/////////////////////////////////////////////
    ");
     84         for(Field field:fs){
     85             sb.append("	");
     86             sb.append(Modifier.toString(field.getModifiers())+" ");
     87             sb.append(field.getType().getSimpleName() + " ");
     88             sb.append(field.getName()+";
    ");
     89         }
     90         //sb.append("}");
     91         sb.append("///////////////////////////////////////////////////////////////////////////////////////////////////////
    ");
     92         //System.out.println(sb);
     93         return sb.toString();
     94     }
     95      
     96     /**
     97      * 根据Class c 对象获取所有方法
     98      * @param c
     99      * @return
    100      */
    101     public String getMethods(Class c)
    102     {
    103         
    104         Method[] ms = c.getDeclaredMethods();
    105         //反编译
    106         StringBuffer sb = new StringBuffer();
    107 //        sb.append(Modifier.toString(c.getModifiers())+" class ");
    108 //        sb.append(c.getSimpleName()+"{
    ");
    109         sb.append("///////////////////////////////////////the Methods of Class/////////////////////////////////////////////
    ");
    110         for(Method m:ms){
    111             sb.append("	");
    112             sb.append(Modifier.toString(m.getModifiers())+" ");
    113             sb.append(m.getReturnType().getSimpleName()+" ");
    114             sb.append(m.getName()+"(");
    115 
    116             //形参
    117             Class[] parameterTypes = m.getParameterTypes();
    118             for(int i=0;i<parameterTypes.length;i++){
    119                 Class parameterType = parameterTypes[i];
    120                 if(i==parameterTypes.length-1){
    121                     sb.append(parameterType.getSimpleName());
    122                 }else{
    123                     sb.append(parameterType.getSimpleName()+",");
    124                 }
    125                 
    126             }
    127 
    128             sb.append("){}
    ");
    129         }
    130 
    131         //sb.append("}");
    132         sb.append("///////////////////////////////////////////////////////////////////////////////////////////////////////
    ");
    133         //System.out.println(sb);
    134         return sb.toString();
    135     }
    136     
    137     /**
    138      * 通过Class c 获取所有构造方法
    139      * @param c
    140      * @return
    141      */
    142     public String getConstructors(Class c)
    143     {
    144         //获取所有的构造
    145         Constructor[] cs = c.getDeclaredConstructors();
    146         //反编译
    147         StringBuffer sb = new StringBuffer();
    148         
    149         //sb.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+"{
    ");
    150         sb.append("///////////////////////////////////////the Constructors of Class/////////////////////////////////////////////
    ");
    151         //构造方法
    152         for(Constructor con:cs){
    153             sb.append("	");
    154             sb.append(Modifier.toString(con.getModifiers()) + " ");
    155             sb.append(c.getSimpleName()+"(");
    156             //形参
    157             Class[] parameterTypes = con.getParameterTypes();
    158             for(int i=0;i<parameterTypes.length;i++){
    159                 Class parameterType = parameterTypes[i];
    160                 if(i==parameterTypes.length-1){
    161                     sb.append(parameterType.getSimpleName());
    162                 }else{
    163                     sb.append(parameterType.getSimpleName()+",");
    164                 }
    165                 
    166             }
    167             sb.append("){}
    ");
    168         }
    169         sb.append("///////////////////////////////////////////////////////////////////////////////////////////////////////
    ");
    170         //sb.append("}");
    171 
    172         //System.out.println(sb);
    173         return sb.toString();
    174     }
    175     
    176     /**
    177      * 通过反射机制获取String类的父类和父接口
    178      * @param c
    179      * @return
    180      */
    181     public String getSuperClass(Class c)
    182     {
    183         StringBuffer sb = new StringBuffer();
    184         //获取父类
    185         Class superClass = c.getSuperclass();
    186 
    187         //System.out.println(superClass.getName());
    188 
    189         sb.append("superClass: "+superClass.getName()+"
    ");
    190         //获取父接口
    191         Class[] ins = c.getInterfaces();
    192         sb.append("Interfaces: 
    ");
    193         for(Class in:ins){
    194             //System.out.println(in.getName());
    195             sb.append(in.getName()+"
    ");
    196         }
    197         return sb.toString();
    198     }
    199     
    200     
    201     /**
    202      * 获取设置某个特定的属性
    203      * @param c
    204      * @return
    205      * @throws Exception
    206      */
    207     public String getFiled(Class c) throws Exception
    208     {
    209         //获取id属性
    210         Field idF = c.getDeclaredField("hash");
    211 
    212         //获取到某个特定的属性可以用来?set , get
    213         Object o = c.newInstance();
    214         
    215         //打破封装
    216         idF.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
    217 
    218         //给o对象的id属性赋值"110"
    219         idF.set(o, 10); //set
    220 
    221         //get
    222         //System.out.println("hash = "+idF.get(o));
    223         return "hash = "+ idF.get(o)+"
    ";
    224     }
    225     
    226     /**
    227      * 获取并执行某个特定的构造方法
    228      * @param c
    229      * @return
    230      * @throws Exception
    231      */
    232     
    233     public String getMethod(Class c) throws Exception
    234     {
    235         //获取特定的构造方法
    236         Constructor con = c.getDeclaredConstructor(String.class);
    237         
    238         //3.创建对象
    239         Object o = con.newInstance("this is a test");
    240 
    241         //System.out.println(o);
    242         return o.toString();
    243     }
    244     
    245     
    246 }

    2.通过读取配置文件的方式可以降低程序的耦合度,同时通过反射机制和读取配置文件的方式,程序在运行时才加载,这样也在一方面说来减轻了程序的负担。

    classInfo.properties

    1 className=java.lang.String
    2 #you need input the whole name of class
    3 #className=User

    3.反编译输出到文件的结果为:

    classInfo.txt

      1 public final class String{
      2 ///////////////////////////////////////the Fileds of Class/////////////////////////////////////////////
      3     private final char[] value;
      4     private final int offset;
      5     private final int count;
      6     private int hash;
      7     private static final long serialVersionUID;
      8     private static final ObjectStreamField[] serialPersistentFields;
      9     public static final Comparator CASE_INSENSITIVE_ORDER;
     10 ///////////////////////////////////////////////////////////////////////////////////////////////////////
     11 ///////////////////////////////////////the Constructors of Class/////////////////////////////////////////////
     12     public String(byte[],int,int){}
     13     public String(byte[],Charset){}
     14     public String(byte[],String){}
     15     public String(byte[],int,int,Charset){}
     16     public String(byte[],int,int,String){}
     17      String(int,int,char[]){}
     18     public String(StringBuilder){}
     19     public String(StringBuffer){}
     20     public String(byte[]){}
     21     public String(int[],int,int){}
     22     public String(){}
     23     public String(char[]){}
     24     public String(String){}
     25     public String(char[],int,int){}
     26     public String(byte[],int){}
     27     public String(byte[],int,int,int){}
     28 ///////////////////////////////////////////////////////////////////////////////////////////////////////
     29 ///////////////////////////////////////the Methods of Class/////////////////////////////////////////////
     30     public boolean equals(Object){}
     31     public String toString(){}
     32     public int hashCode(){}
     33     public volatile int compareTo(Object){}
     34     public int compareTo(String){}
     35     static int indexOf(char[],int,int,char[],int,int,int){}
     36     public int indexOf(String){}
     37     public int indexOf(int,int){}
     38     public int indexOf(int){}
     39     public int indexOf(String,int){}
     40     public static String valueOf(char){}
     41     public static String valueOf(boolean){}
     42     public static String valueOf(float){}
     43     public static String valueOf(long){}
     44     public static String valueOf(Object){}
     45     public static String valueOf(char[]){}
     46     public static String valueOf(int){}
     47     public static String valueOf(char[],int,int){}
     48     public static String valueOf(double){}
     49     public String[] split(String,int){}
     50     public String[] split(String){}
     51     public boolean startsWith(String){}
     52     public boolean startsWith(String,int){}
     53     public CharSequence subSequence(int,int){}
     54     public String substring(int){}
     55     public String substring(int,int){}
     56     public char[] toCharArray(){}
     57     public String toLowerCase(){}
     58     public String toLowerCase(Locale){}
     59     public String toUpperCase(Locale){}
     60     public String toUpperCase(){}
     61     public String trim(){}
     62     public int codePointBefore(int){}
     63     public int codePointCount(int,int){}
     64     public int compareToIgnoreCase(String){}
     65     public boolean contentEquals(StringBuffer){}
     66     public boolean contentEquals(CharSequence){}
     67     public boolean equalsIgnoreCase(String){}
     68     private int indexOfSupplementary(int,int){}
     69     private int lastIndexOfSupplementary(int,int){}
     70     public int offsetByCodePoints(int,int){}
     71     public boolean regionMatches(int,String,int,int){}
     72     public boolean regionMatches(boolean,int,String,int,int){}
     73     public char charAt(int){}
     74     private static void checkBounds(byte[],int,int){}
     75     public int codePointAt(int){}
     76     public String concat(String){}
     77     public boolean contains(CharSequence){}
     78     public static String copyValueOf(char[],int,int){}
     79     public static String copyValueOf(char[]){}
     80     public boolean endsWith(String){}
     81     public static transient String format(String,Object[]){}
     82     public static transient String format(Locale,String,Object[]){}
     83     public byte[] getBytes(Charset){}
     84     public byte[] getBytes(){}
     85     public void getBytes(int,int,byte[],int){}
     86     public byte[] getBytes(String){}
     87      void getChars(char[],int){}
     88     public void getChars(int,int,char[],int){}
     89     public native String intern(){}
     90     public boolean isEmpty(){}
     91     public int lastIndexOf(String,int){}
     92     public int lastIndexOf(String){}
     93     public int lastIndexOf(int,int){}
     94     public int lastIndexOf(int){}
     95     static int lastIndexOf(char[],int,int,char[],int,int,int){}
     96     public int length(){}
     97     public boolean matches(String){}
     98     public String replace(CharSequence,CharSequence){}
     99     public String replace(char,char){}
    100     public String replaceAll(String,String){}
    101     public String replaceFirst(String,String){}
    102 ///////////////////////////////////////////////////////////////////////////////////////////////////////
    103 }
    104 superClass: java.lang.Object
    105 Interfaces: 
    106 java.io.Serializable
    107 java.lang.Comparable
    108 java.lang.CharSequence
    109 hash = 10
    110 this is a test

    而还有可以利用Java反射技术将查询结果封装为对象,这在数据库查询方便提供了广大的便利,后续再补充,谢谢。

  • 相关阅读:
    java面试-Java内存模型(JMM)
    github常用操作
    java面试-生产环境服务器变慢,谈谈你的诊断思路
    java面试-JVM调优和参数配置,如何查看JVM系统参数默认值
    java面试-死锁产生、定位分析和修复
    Scalable IO in Java【java高效IO】
    java面试-JDK自带的JVM 监控和性能分析工具用过哪些?
    Docker简介
    使用docker部署项目
    公司系统遇到的问题,虽然解决了,但是,不知道原因。贴下图片,供下次参考
  • 原文地址:https://www.cnblogs.com/ning1121/p/3932192.html
Copyright © 2011-2022 走看看