Java高级篇(四)——反射
2021-06-21 17:03
                         标签:prot   desc   基本使用   动态获取   转换   text   stat   成员   tty      之前写到了设计模式的代理模式,因为下一篇动态代理等内容需要用到反射的知识,所以在之前Java篇的基础上再写一篇有关反射的内容,还是以实际的程序为主,了解反射是做什么的、应该怎么用。   反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。   Java反射机制主要提供了以下功能:    Java中主要由以下的类来实现Java反射机制(这些类都位于java.lang.reflect包中): Class类:代表一个类。 Field类:代表类的成员变量(成员变量也称为类的属性)。 Method类:代表类的方法。 Constructor类:代表类的构造方法。 Array类:提供了动态创建数组,以及访问数组的元素的静态方法。   下面分步说明以下如何通过反射获取我们需要的内容。   我们先随意写一个Customer类(就是一个PO类),然后看看如何通过反射对这个类进行操作。   这个类用来演示Reflection API的基本使用方法。这里自定义的copy方法是用来创建一个和参数objcet同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将其返回。   下面分析一下上述代码。   首先,通过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()方法构造一个实例。   第三步,获得对象的所有属性,即通过Class类的getDeclaredFields()方法返回类的所有属性,包括public、protected、default和private访问级别的属性,   第四步,获得每个属性相应的get/set方法,然后执行这些方法,把原来的对象属性拷贝到新的对象中。   这里我们可以写一个InvokeTester的类,然后运用反射机制调用一个InvokeTester对象的add()方法(自定义方法),如add()方法的两个参数为int类型,那么获取表示add()方法的Method对象代码如下:    上述代码中也有用到Method的invoke方法,其接收参数必须为对象,如果参数为基本数据类型,必须转换为相应的包装类型的对象,如int要转换为Integer。而invoke方法的返回值总是对象,如果实际被调用的方法的返回类型是基本数据类型,那么invoke方法会将其转换为相应的包装类型的对象,再将其返回。   下面简单测试一下,具体的方法调用如上面提到的add方法,可自行编写(具体实例见下篇):    运行结果如下:      下面我们尝试着通过反射机制对一个jar包中的类进行分析,把类中所有的属性和方法提取出来,并写入到一个文件里中。   目录结构如下:      主要代码部分,通过反射获取类、属性及方法。   进行写文件操作。   这里我们需要在项目下新建一个lib文件夹,然后将要解析的jar包放入其中,比如这里我们放入jdk的dt.jar。目录结构如下:      执行程序:   运行结果如下:    Java高级篇(四)——反射 标签:prot   desc   基本使用   动态获取   转换   text   stat   成员   tty    原文地址:https://www.cnblogs.com/adamjwh/p/9683705.html一、什么是反射
  1. 反射机制的功能
  2. 实现反射机制的类
二、反射的使用
  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类
 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
Class classType=object.getClass();
Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
Field fields[]=classType.getDeclaredFields();
Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});
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 }   

三、具体实例

  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 /**
11  * @ClassName: ReflexDemo
12  * @Description: 通过反射获取类、属性及方法
13  * @author adamjwh
14  * @date 2018年5月28日
15  *
16  */
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
  2. WriteFile类
 1 import java.io.BufferedWriter;
 2 import java.io.File;
 3 import java.io.FileWriter;
 4 
 5 /**
 6  * @ClassName: WriteFile
 7  * @Description: 写文件操作
 8  * @author adamjwh
 9  * @date 2018年5月28日
10  *
11  */
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类

 1 /**
 2  * @ClassName: Main
 3  * @Description: 
 4  * @author adamjwh
 5  * @date 2018年5月28日
 6  *
 7  */
 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 }
