iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何解析Java反射
  • 181
分享到

如何解析Java反射

2023-06-25 12:06:14 181人浏览 独家记忆
摘要

今天就跟大家聊聊有关如何解析Java反射,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、什么是反射反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任

今天就跟大家聊聊有关如何解析Java反射,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

一、什么是反射

反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。

1. 反射机制的功能

Java反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类。

  • 在运行时构造任意一个类的对象。

  • 在运行时判断任意一个类所具有的成员变量和方法。

  • 在运行时调用任意一个对象的方法。

  • 生成动态代理。  

2. 实现反射机制的类

Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):

  • Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。

  • Method类:代表类的方法。

  • Constructor类:代表类的构造方法。

  • Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

二、反射的使用

下面分步说明以下如何通过反射获取我们需要的内容。

我们先随意写一个Customer类(就是一个PO类),然后看看如何通过反射对这个类进行操作。

1. Customer类

  之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的、应该怎么用。一、什么是反射  反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。  1. 反射机制的功能  Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类。在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。在运行时调用任意一个对象的方法。生成动态代理。  2. 实现反射机制的类   Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。Method类:代表类的方法。Constructor类:代表类的构造方法。Array类:提供了动态创建数组,以及访问数组的元素的静态方法。二、反射的使用  下面分步说明以下如何通过反射获取我们需要的内容。  我们先随意写一个Customer类(就是一个PO类),然后看看如何通过反射对这个类进行操作。  1. Customer类 1 public class Customer { 2      3     private Long id; 4     private String name; 5     private int age; 6        7     public Customer() {} 8      9     public Customer(String name,int age) {10         this.name = name;11         this.age = age;12     }13       14     public Long getId() {15         return id;16     }17     public void setId(Long id) {18         this.id=id;19     }20     public String getName() {21         return name;22     }23     public void setName(String name) {24         this.name=name;25     }26     public int getAge() {27         return age;28     }29     public void setAge(int age) {30         this.age=age;31     }32 33 }   2. ReflectTester类  这个类用来演示Reflectioapi的基本使用方法。这里自定义的copy方法是用来创建一个和参数objcet同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将其返回。 1 import java.lang.reflect.Field; 2 import java.lang.reflect.Method; 3  4 public class ReflectTester { 5      6     public Object copy(Object object) throws Exception{ 7         //获得对象的类型 8         Class classType=object.getClass(); 9         System.out.println("Class:"+classType.getName());10 11         //通过默认构造方法创建一个新的对象12         Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});13 14         //获得对象的所有属性15         Field fields[]=classType.getDeclaredFields();16 17         for(int i=0; i<fields.length;i++){18               Field field=fields[i];19 20               String fieldName=field.getName();21               String firstLetter=fieldName.substring(0,1).toUpperCase();22               //获得和属性对应的getXXX()方法的名字23               String getMethodName="get"+firstLetter+fieldName.substring(1);24               //获得和属性对应的setXXX()方法的名字25               String setMethodName="set"+firstLetter+fieldName.substring(1);26 27               //获得和属性对应的getXXX()方法28               Method getMethod=classType.getMethod(getMethodName,new Class[]{});29               //获得和属性对应的setXXX()方法30               Method setMethod=classType.getMethod(setMethodName,new Class[]{field.getType()});31 32               //调用原对象的getXXX()方法33               Object value=getMethod.invoke(object,new Object[]{});34               System.out.println(fieldName+":"+value);35               //调用拷贝对象的setXXX()方法36              setMethod.invoke(objectCopy,new Object[]{value});37         }38         return objectCopy;39      }40 41 }  下面分析一下上述代码。  首先,通过Object类中的getClass()方法获取对象的类型。Class classType=object.getClass();  而Class类是Reflection API中的核心类,主要方法如下:getName():获得类的完整名字。 getFields():获得类的public类型的属性。getDeclaredFields():获得类的所有属性。getMethods():获得类的public类型的方法。getDeclaredMethods():获得类的所有方法。getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。getConstrutors():获得类的public类型的构造方法。getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。newInstance():通过类的不带参数的构造方法创建这个类的一个对象。  第二步,通过默认构造方法创建一个新的对象,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});  第三步,获得对象的所有属性,即通过Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、default和private访问级别的属性,Field fields[]=classType.getDeclaredFields();  第四步,获得每个属性相应的get/set方法,然后执行这些方法,把原来的对象属性拷贝到新的对象中。  这里我们可以写一个InvokeTester的类,然后运用反射机制调用一个InvokeTester对象的add()方法(自定义方法),如add()方法的两个参数为int类型,那么获取表示add()方法的Method对象代码如下:Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});   上述代码中也有用到Method的invoke方法,其接收参数必须为对象,如果参数为基本数据类型,必须转换为相应的包装类型的对象,如int要转换为Integer。而invoke方法的返回值总是对象,如果实际被调用的方法的返回类型是基本数据类型,那么invoke方法会将其转换为相应的包装类型的对象,再将其返回。  下面简单测试一下,具体的方法调用如上面提到的add方法,可自行编写(具体实例见下篇):1 public static void main(String[] args) throws Exception {2   Customer customer = new Customer();3   customer.setId(10L);4   customer.setName("adam");5   customer.setAge(3);6         7   new ReflectTester().copy(customer);8 }      运行结果如下:  三、具体实例  下面我们尝试着通过反射机制对一个jar包中的类进行分析,把类中所有的属性和方法提取出来,并写入到一个文件里中。  目录结构如下:    1. ReflexDemo类  主要代码部分,通过反射获取类、属性及方法。 1 import java.io.File; 2 import java.lang.reflect.Field; 3 import java.lang.reflect.Method; 4 import java.net.URL; 5 import java.net.URLClassLoader; 6 import java.util.Enumeration; 7 import java.util.jar.JarEntry; 8 import java.util.jar.JarFile; 9 10 17 public class ReflexDemo {18 19     private static StringBuffer sBuffer;20     21     public static void getJar(String jar) throws Exception {22         try {23             File file = new File(jar);24             URL url = file.toURI().toURL();25             URLClassLoader classLoader = new URLClassLoader(new URL[] { url },26                     Thread.currentThread().getContextClassLoader());27 28             JarFile jarFile = new JarFile(jar);29             Enumeration<JarEntry> enumeration = jarFile.entries();30             JarEntry jarEntry;31             32             sBuffer = new StringBuffer();    //存数据33 34             while (enumeration.hasMoreElements()) {35                 jarEntry = enumeration.nextElement();36 37                 if (jarEntry.getName().indexOf("META-INF") < 0) {38                     String classFullName = jarEntry.getName();39                     if (classFullName.indexOf(".class") < 0) {40                         classFullName = classFullName.substring(0, classFullName.length() - 1);41                     } else {42                         // 去除后缀.class,获得类名43                         String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");44                         Class<?> myClass = classLoader.loadClass(className);45                         sBuffer.append("类名\t:" + className);46                         System.out.println("类名\t:" + className);47 48                         // 获得属性名49                         Class<?> clazz = Class.forName(className);50                         Field[] fields = clazz.getDeclaredFields();51                         for (Field field : fields) {52                             sBuffer.append("属性名\t:" + field.getName() + "\n");53                             System.out.println("属性名\t:" + field.getName());54                             sBuffer.append("-属性类型\t:" + field.getType() + "\n");55                             System.out.println("-属性类型\t:" + field.getType());56                         }57 58                         // 获得方法名59                         Method[] methods = myClass.getMethods();60                         for (Method method : methods) {61                             if (method.toString().indexOf(className) > 0) {62                                 sBuffer.append("方法名\t:" + method.toString().substring(method.toString().indexOf(className)) + "\n");63                                 System.out.println("方法名\t:" + method.toString().substring(method.toString().indexOf(className)));64                             }65                         }66                         sBuffer.append("--------------------------------------------------------------------------------" + "\n");67                         System.out.println("--------------------------------------------------------------------------------");68                     }69                 }70             }71         } catch (Exception e) {72             e.printStackTrace();73         } finally {74             sBuffer.append("End");75             System.out.println("End");76             77             WriteFile.write(sBuffer);    //写文件78         }79     }80 81 }  2. WriteFile类  进行写文件操作。 1 import java.io.BufferedWriter; 2 import java.io.File; 3 import java.io.FileWriter; 4  5 12 public class WriteFile {13 14     private static String pathname = "src/com/adamjwh/jnp/ex14/out.txt";15     16     public static void write(StringBuffer sBuffer) throws Exception {17         File file = new File(pathname);18         BufferedWriter bw = new BufferedWriter(new FileWriter(file));19         20         bw.write(sBuffer.toString());21         bw.close();22     }23     24 }  3. Main类  这里我们需要在项目下新建一个lib文件夹,然后将要解析的jar包放入其中,比如这里我们放入jdk的dt.jar。目录结构如下:    执行程序: 1  8 public class Main { 9     10     private static String jar = "lib/dt.jar";11     12     public static void main(String[] args) throws Exception {13         ReflexDemo.getJar(jar);14     }15 16 }  运行结果如下:  

2. ReflectTester类

这个类用来演示Reflection API的基本使用方法。这里自定义的copy方法是用来创建一个和参数objcet同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将其返回。

  之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的、应该怎么用。一、什么是反射  反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。  1. 反射机制的功能  Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类。在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。在运行时调用任意一个对象的方法。生成动态代理。  2. 实现反射机制的类   Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中):Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。Method类:代表类的方法。Constructor类:代表类的构造方法。Array类:提供了动态创建数组,以及访问数组的元素的静态方法。二、反射的使用  下面分步说明以下如何通过反射获取我们需要的内容。  我们先随意写一个Customer类(就是一个PO类),然后看看如何通过反射对这个类进行操作。  1. Customer类 1 public class Customer { 2      3     private Long id; 4     private String name; 5     private int age; 6        7     public Customer() {} 8      9     public Customer(String name,int age) {10         this.name = name;11         this.age = age;12     }13       14     public Long getId() {15         return id;16     }17     public void setId(Long id) {18         this.id=id;19     }20     public String getName() {21         return name;22     }23     public void setName(String name) {24         this.name=name;25     }26     public int getAge() {27         return age;28     }29     public void setAge(int age) {30         this.age=age;31     }32 33 }   2. ReflectTester类  这个类用来演示Reflection API的基本使用方法。这里自定义的copy方法是用来创建一个和参数objcet同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将其返回。 1 import java.lang.reflect.Field; 2 import java.lang.reflect.Method; 3  4 public class ReflectTester { 5      6     public Object copy(Object object) throws Exception{ 7         //获得对象的类型 8         Class classType=object.getClass(); 9         System.out.println("Class:"+classType.getName());10 11         //通过默认构造方法创建一个新的对象12         Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});13 14         //获得对象的所有属性15         Field fields[]=classType.getDeclaredFields();16 17         for(int i=0; i<fields.length;i++){18               Field field=fields[i];19 20               String fieldName=field.getName();21               String firstLetter=fieldName.substring(0,1).toUpperCase();22               //获得和属性对应的getXXX()方法的名字23               String getMethodName="get"+firstLetter+fieldName.substring(1);24               //获得和属性对应的setXXX()方法的名字25               String setMethodName="set"+firstLetter+fieldName.substring(1);26 27               //获得和属性对应的getXXX()方法28               Method getMethod=classType.getMethod(getMethodName,new Class[]{});29               //获得和属性对应的setXXX()方法30               Method setMethod=classType.getMethod(setMethodName,new Class[]{field.getType()});31 32               //调用原对象的getXXX()方法33               Object value=getMethod.invoke(object,new Object[]{});34               System.out.println(fieldName+":"+value);35               //调用拷贝对象的setXXX()方法36              setMethod.invoke(objectCopy,new Object[]{value});37         }38         return objectCopy;39      }40 41 }  下面分析一下上述代码。  首先,通过Object类中的getClass()方法获取对象的类型。Class classType=object.getClass();  而Class类是Reflection API中的核心类,主要方法如下:getName():获得类的完整名字。 getFields():获得类的public类型的属性。getDeclaredFields():获得类的所有属性。getMethods():获得类的public类型的方法。getDeclaredMethods():获得类的所有方法。getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。getConstrutors():获得类的public类型的构造方法。getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。newInstance():通过类的不带参数的构造方法创建这个类的一个对象。  第二步,通过默认构造方法创建一个新的对象,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});  第三步,获得对象的所有属性,即通过Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、default和private访问级别的属性,Field fields[]=classType.getDeclaredFields();  第四步,获得每个属性相应的get/set方法,然后执行这些方法,把原来的对象属性拷贝到新的对象中。  这里我们可以写一个InvokeTester的类,然后运用反射机制调用一个InvokeTester对象的add()方法(自定义方法),如add()方法的两个参数为int类型,那么获取表示add()方法的Method对象代码如下:Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});   上述代码中也有用到Method的invoke方法,其接收参数必须为对象,如果参数为基本数据类型,必须转换为相应的包装类型的对象,如int要转换为Integer。而invoke方法的返回值总是对象,如果实际被调用的方法的返回类型是基本数据类型,那么invoke方法会将其转换为相应的包装类型的对象,再将其返回。  下面简单测试一下,具体的方法调用如上面提到的add方法,可自行编写(具体实例见下篇):1 public static void main(String[] args) throws Exception {2   Customer customer = new Customer();3   customer.setId(10L);4   customer.setName("adam");5   customer.setAge(3);6         7   new ReflectTester().copy(customer);8 }      运行结果如下:  三、具体实例  下面我们尝试着通过反射机制对一个jar包中的类进行分析,把类中所有的属性和方法提取出来,并写入到一个文件里中。  目录结构如下:    1. ReflexDemo类  主要代码部分,通过反射获取类、属性及方法。 1 import java.io.File; 2 import java.lang.reflect.Field; 3 import java.lang.reflect.Method; 4 import java.net.URL; 5 import java.net.URLClassLoader; 6 import java.util.Enumeration; 7 import java.util.jar.JarEntry; 8 import java.util.jar.JarFile; 9 10 17 public class ReflexDemo {18 19     private static StringBuffer sBuffer;20     21     public static void getJar(String jar) throws Exception {22         try {23             File file = new File(jar);24             URL url = file.toURI().toURL();25             URLClassLoader classLoader = new URLClassLoader(new URL[] { url },26                     Thread.currentThread().getContextClassLoader());27 28             JarFile jarFile = new JarFile(jar);29             Enumeration<JarEntry> enumeration = jarFile.entries();30             JarEntry jarEntry;31             32             sBuffer = new StringBuffer();    //存数据33 34             while (enumeration.hasMoreElements()) {35                 jarEntry = enumeration.nextElement();36 37                 if (jarEntry.getName().indexOf("META-INF") < 0) {38                     String classFullName = jarEntry.getName();39                     if (classFullName.indexOf(".class") < 0) {40                         classFullName = classFullName.substring(0, classFullName.length() - 1);41                     } else {42                         // 去除后缀.class,获得类名43                         String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");44                         Class<?> myClass = classLoader.loadClass(className);45                         sBuffer.append("类名\t:" + className);46                         System.out.println("类名\t:" + className);47 48                         // 获得属性名49                         Class<?> clazz = Class.forName(className);50                         Field[] fields = clazz.getDeclaredFields();51                         for (Field field : fields) {52                             sBuffer.append("属性名\t:" + field.getName() + "\n");53                             System.out.println("属性名\t:" + field.getName());54                             sBuffer.append("-属性类型\t:" + field.getType() + "\n");55                             System.out.println("-属性类型\t:" + field.getType());56                         }57 58                         // 获得方法名59                         Method[] methods = myClass.getMethods();60                         for (Method method : methods) {61                             if (method.toString().indexOf(className) > 0) {62                                 sBuffer.append("方法名\t:" + method.toString().substring(method.toString().indexOf(className)) + "\n");63                                 System.out.println("方法名\t:" + method.toString().substring(method.toString().indexOf(className)));64                             }65                         }66                         sBuffer.append("--------------------------------------------------------------------------------" + "\n");67                         System.out.println("--------------------------------------------------------------------------------");68                     }69                 }70             }71         } catch (Exception e) {72             e.printStackTrace();73         } finally {74             sBuffer.append("End");75             System.out.println("End");76             77             WriteFile.write(sBuffer);    //写文件78         }79     }80 81 }  2. WriteFile类  进行写文件操作。 1 import java.io.BufferedWriter; 2 import java.io.File; 3 import java.io.FileWriter; 4  5 12 public class WriteFile {13 14     private static String pathname = "src/com/adamjwh/jnp/ex14/out.txt";15     16     public static void write(StringBuffer sBuffer) throws Exception {17         File file = new File(pathname);18         BufferedWriter bw = new BufferedWriter(new FileWriter(file));19         20         bw.write(sBuffer.toString());21         bw.close();22     }23     24 }  3. Main类  这里我们需要在项目下新建一个lib文件夹,然后将要解析的jar包放入其中,比如这里我们放入jdk的dt.jar。目录结构如下:    执行程序: 1  8 public class Main { 9     10     private static String jar = "lib/dt.jar";11     12     public static void main(String[] args) throws Exception {13         ReflexDemo.getJar(jar);14     }15 16 }  运行结果如下:  

下面分析一下上述代码。

首先,通过Object类中的getClass()方法获取对象的类型。

Class classType=object.getClass();

而Class类是Reflection API中的核心类,主要方法如下:

  • getName():获得类的完整名字。 getFields():获得类的public类型的属性。

  • getDeclaredFields():获得类的所有属性。

  • getMethods():获得类的public类型的方法。

  • getDeclaredMethods():获得类的所有方法。

  • getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。

  • getConstrutors():获得类的public类型的构造方法。

  • getConstrutor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes参数指定构造方法的参数类型。

  • newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

第二步,通过默认构造方法创建一个新的对象,即先调用Class类的getConstructor()方法获得一个Constructor对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。

Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

第三步,获得对象的所有属性,即通过Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、default和private访问级别的属性,

Field fields[]=classType.getDeclaredFields();

第四步,获得每个属性相应的get/set方法,然后执行这些方法,把原来的对象属性拷贝到新的对象中。

这里我们可以写一个InvokeTester的类,然后运用反射机制调用一个InvokeTester对象的add()方法(自定义方法),如add()方法的两个参数为int类型,那么获取表示add()方法的Method对象代码如下:

Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});

上述代码中也有用到Method的invoke方法,其接收参数必须为对象,如果参数为基本数据类型,必须转换为相应的包装类型的对象,如int要转换为Integer。而invoke方法的返回值总是对象,如果实际被调用的方法的返回类型是基本数据类型,那么invoke方法会将其转换为相应的包装类型的对象,再将其返回。

下面简单测试一下,具体的方法调用如上面提到的add方法,可自行编写(具体实例见下篇):

public static void main(String[] args) throws Exception {  Customer customer = new Customer();  customer.setId(10L);  customer.setName("adam");  customer.setAge(3);  new ReflectTester().copy(customer);}

运行结果如下:

如何解析Java反射

三、具体实例

下面我们尝试着通过反射机制对一个jar包中的类进行分析,把类中所有的属性和方法提取出来,并写入到一个文件里中。

目录结构如下:

如何解析Java反射

1. ReflexDemo类

主要代码部分,通过反射获取类、属性及方法。

import java.io.File;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.Enumeration;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class ReflexDemo {    private static StringBuffer sBuffer;    public static void getJar(String jar) throws Exception {        try {            File file = new File(jar);            URL url = file.toURI().toURL();            URLClassLoader classLoader = new URLClassLoader(new URL[] { url },                    Thread.currentThread().getContextClassLoader());            JarFile jarFile = new JarFile(jar);            Enumeration<JarEntry> enumeration = jarFile.entries();            JarEntry jarEntry;            sBuffer = new StringBuffer();    //存数据            while (enumeration.hasMoreElements()) {                jarEntry = enumeration.nextElement();                if (jarEntry.getName().indexOf("META-INF") < 0) {                    String classFullName = jarEntry.getName();                    if (classFullName.indexOf(".class") < 0) {                        classFullName = classFullName.substring(0, classFullName.length() - 1);                    } else {                        // 去除后缀.class,获得类名                        String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");                        Class<?> myClass = classLoader.loadClass(className);                        sBuffer.append("类名\t:" + className);                        System.out.println("类名\t:" + className);                        // 获得属性名                        Class<?> clazz = Class.forName(className);                        Field[] fields = clazz.getDeclaredFields();                        for (Field field : fields) {                            sBuffer.append("属性名\t:" + field.getName() + "\n");                            System.out.println("属性名\t:" + field.getName());                            sBuffer.append("-属性类型\t:" + field.getType() + "\n");                            System.out.println("-属性类型\t:" + field.getType());                        }                        // 获得方法名                        Method[] methods = myClass.getMethods();                        for (Method method : methods) {                            if (method.toString().indexOf(className) > 0) {                                sBuffer.append("方法名\t:" + method.toString().substring(method.toString().indexOf(className)) + "\n");                                System.out.println("方法名\t:" + method.toString().substring(method.toString().indexOf(className)));                            }                        }                        sBuffer.append("--------------------------------------------------------------------------------" + "\n");                        System.out.println("--------------------------------------------------------------------------------");                    }                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            sBuffer.append("End");            System.out.println("End");            WriteFile.write(sBuffer);    //写文件        }    }}

2. WriteFile类

进行写文件操作。

import java.io.File;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.Enumeration;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class ReflexDemo {    private static StringBuffer sBuffer;    public static void getJar(String jar) throws Exception {        try {            File file = new File(jar);            URL url = file.toURI().toURL();            URLClassLoader classLoader = new URLClassLoader(new URL[] { url },                    Thread.currentThread().getContextClassLoader());            JarFile jarFile = new JarFile(jar);            Enumeration<JarEntry> enumeration = jarFile.entries();            JarEntry jarEntry;            sBuffer = new StringBuffer();    //存数据            while (enumeration.hasMoreElements()) {                jarEntry = enumeration.nextElement();                if (jarEntry.getName().indexOf("META-INF") < 0) {                    String classFullName = jarEntry.getName();                    if (classFullName.indexOf(".class") < 0) {                        classFullName = classFullName.substring(0, classFullName.length() - 1);                    } else {                        // 去除后缀.class,获得类名                        String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");                        Class<?> myClass = classLoader.loadClass(className);                        sBuffer.append("类名\t:" + className);                        System.out.println("类名\t:" + className);                        // 获得属性名                        Class<?> clazz = Class.forName(className);                        Field[] fields = clazz.getDeclaredFields();                        for (Field field : fields) {                            sBuffer.append("属性名\t:" + field.getName() + "\n");                            System.out.println("属性名\t:" + field.getName());                            sBuffer.append("-属性类型\t:" + field.getType() + "\n");                            System.out.println("-属性类型\t:" + field.getType());                        }                        // 获得方法名                        Method[] methods = myClass.getMethods();                        for (Method method : methods) {                            if (method.toString().indexOf(className) > 0) {                                sBuffer.append("方法名\t:" + method.toString().substring(method.toString().indexOf(className)) + "\n");                                System.out.println("方法名\t:" + method.toString().substring(method.toString().indexOf(className)));                            }                        }                        sBuffer.append("--------------------------------------------------------------------------------" + "\n");                        System.out.println("--------------------------------------------------------------------------------");                    }                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            sBuffer.append("End");            System.out.println("End");            WriteFile.write(sBuffer);    //写文件        }    }}

3. Main类

这里我们需要在项目下新建一个lib文件夹,然后将要解析的jar包放入其中,比如这里我们放入jdk的dt.jar。目录结构如下:

如何解析Java反射

执行程序:

import java.io.File;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.Enumeration;import java.util.jar.JarEntry;import java.util.jar.JarFile;public class ReflexDemo {    private static StringBuffer sBuffer;    public static void getJar(String jar) throws Exception {        try {            File file = new File(jar);            URL url = file.toURI().toURL();            URLClassLoader classLoader = new URLClassLoader(new URL[] { url },                    Thread.currentThread().getContextClassLoader());            JarFile jarFile = new JarFile(jar);            Enumeration<JarEntry> enumeration = jarFile.entries();            JarEntry jarEntry;            sBuffer = new StringBuffer();    //存数据            while (enumeration.hasMoreElements()) {                jarEntry = enumeration.nextElement();                if (jarEntry.getName().indexOf("META-INF") < 0) {                    String classFullName = jarEntry.getName();                    if (classFullName.indexOf(".class") < 0) {                        classFullName = classFullName.substring(0, classFullName.length() - 1);                    } else {                        // 去除后缀.class,获得类名                        String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");                        Class<?> myClass = classLoader.loadClass(className);                        sBuffer.append("类名\t:" + className);                        System.out.println("类名\t:" + className);                        // 获得属性名                        Class<?> clazz = Class.forName(className);                        Field[] fields = clazz.getDeclaredFields();                        for (Field field : fields) {                            sBuffer.append("属性名\t:" + field.getName() + "\n");                            System.out.println("属性名\t:" + field.getName());                            sBuffer.append("-属性类型\t:" + field.getType() + "\n");                            System.out.println("-属性类型\t:" + field.getType());                        }                        // 获得方法名                        Method[] methods = myClass.getMethods();                        for (Method method : methods) {                            if (method.toString().indexOf(className) > 0) {                                sBuffer.append("方法名\t:" + method.toString().substring(method.toString().indexOf(className)) + "\n");                                System.out.println("方法名\t:" + method.toString().substring(method.toString().indexOf(className)));                            }                        }                        sBuffer.append("--------------------------------------------------------------------------------" + "\n");                        System.out.println("--------------------------------------------------------------------------------");                    }                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            sBuffer.append("End");            System.out.println("End");            WriteFile.write(sBuffer);    //写文件        }    }}

运行结果如下:

如何解析Java反射

看完上述内容,你们对如何解析Java反射有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注编程网精选频道,感谢大家的支持。

--结束END--

本文标题: 如何解析Java反射

本文链接: https://www.lsjlt.com/news/304926.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何解析Java反射
    今天就跟大家聊聊有关如何解析Java反射,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、什么是反射反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任...
    99+
    2023-06-25
  • 如何理解Java反射技术
    本篇内容介绍了“如何理解Java反射技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、前期概要1、 什么是反射Java 反射机制在程序运...
    99+
    2023-06-02
  • Java反射如何使用
    这篇文章将为大家详细讲解有关Java反射如何使用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。反射相信刚接触Java的,第一句肯定会问什么是反射呢?反射有什么作用呢?为什么使用反射呢?首先反射是Java的...
    99+
    2023-06-25
  • 如何理解反射
    这篇文章主要介绍“如何理解反射”,在日常操作中,相信很多人在如何理解反射问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解反射”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!反射的思想及作用有反必有正,...
    99+
    2023-06-16
  • 深入解析Java反射之基础篇
    目录前言一、回顾:什么是反射?二、反射的主要用途三、反射的基本运用1、获得 Class 对象2、判断是否为某个类的实例3、创建实例4、获取方法5、获取构造器信息6、获取类的成员变量(...
    99+
    2024-04-02
  • Java 反射(Reflect)详解
    目录一 首先我们的去知道什么是反射?二(刨根问底)知道是什么还需要知道什么“成分”组成反射?2.1 Class 对象的获取及使用2.2 拿到碗筷就得去盛饭,拿到了Class就得去操作...
    99+
    2024-04-02
  • java反射详解(3)
    动态代理 【案例】首先来看看如何获得类加载器:  class test{       } class hello{     public static void main(String[] args) {         test t=ne...
    99+
    2023-01-31
    反射 详解 java
  • Java反射的示例分析
    这篇文章主要为大家展示了“Java反射的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java反射的示例分析”这篇文章吧。一、Class类与Java反射Class textFieldC=...
    99+
    2023-06-25
  • Java深入分析讲解反射机制
    目录反射的概述获取Class对象的三种方式通过反射机制获取类的属性通过反射机制访问Java对象的属性反射机制与属性配置文件的配合使用资源绑定器配合使用样例通过反射机制获取类中方法通过...
    99+
    2024-04-02
  • AJPFX反射及反射的应用该如何理解
    本篇文章为大家展示了AJPFX反射及反射的应用该如何理解,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。怎么理解反射,反射的应用        反射就是把Jav...
    99+
    2023-06-02
  • Java反射技术详解
    目录前言一、基本反射技术1.1 根据一个字符串得到一个类getClass方法Class.forNameType属性二、获取类的成员获取类中特定的构造方法调用构造方法调用类的私有方法获...
    99+
    2024-04-02
  • 如何使用Java反射机制
    这篇文章主要介绍“如何使用Java反射机制”,在日常操作中,相信很多人在如何使用Java反射机制问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何使用Java反射机制”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-15
  • Java反射机制详解
    目录类的声明周期不同阶段都可以获取类对象获取Class类对象的方式的场景class类对象的功能如何获取私有变量的值根据有无主方法判断进程和线程反射出现的背景(记住)反射出现的背景类的...
    99+
    2024-04-02
  • Java反射应用指南:如何将Java反射用于实际开发
    1、Java反射的原理及使用方法 Java反射机制是通过Java虚拟机提供的反射API来实现的,主要包括以下几个核心类: Class:表示Java类或接口 Method:表示Java方法 Field:表示Java字段 Construc...
    99+
    2024-02-02
    Java 反射 动态类型 元编程 API探索
  • Java反射机制实例分析
    这篇“Java反射机制实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java反射机制实例分析”文章吧。Java反射机...
    99+
    2023-06-29
  • 如何理解.NET的反射
    这期内容当中小编将会给大家带来有关如何解.NET的反射,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。反射反射提供了封装程序集、模块和类型的对象(Type  类型)。可以使用反射动态创建类型的实例...
    99+
    2023-06-17
  • 如何理解Java反射以及动态代理
    这篇文章主要介绍“如何理解Java反射以及动态代理”,在日常操作中,相信很多人在如何理解Java反射以及动态代理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解Java反射以及动态代理”的疑惑有所帮助!...
    99+
    2023-06-16
  • 深入解析Java中反射中的invoke()方法
    先讲一下java中的反射: 反射就是将类别的各个组成部分进行剖析,可以得到每个组成部分,就可以对每一部分进行操作 反射机制应用场景:逆向代码、动态生成类框架等,使用反射机制能够大大的...
    99+
    2024-04-02
  • Java反射 Field类的使用全方位解析
    Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。 Field 成员变量的介绍 每个成员变量有类型和值。 java....
    99+
    2024-04-02
  • 【Java 基础篇】Java 反射详解
    文章目录 导言一、反射的概念二、反射的原理三、反射的使用示例四、反射的应用场景五、反射的注意事项总结 导言 Java反射是指在运行时动态地获取类的信息,并可以通过该信息来操作类或对象。...
    99+
    2023-09-14
    java python 开发语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作