详述获取字节码文件及其内容的方法
来源:互联网 发布:初中生编程培训 编辑:程序博客网 时间:2024/05/22 00:49
1 简述
Java 的反射机制是指:
- 在运行状态中,对任意一个类(class文件),都能知道这个类的所有属性和方法;对任意一个对象,都能调用这个对象的方法和属性。
简单点说,这种动态的获取信息和动态的调用对象的方法的功能就是 Java 的反射机制。利用 Java 的反射机制,我们可以很容易的获取类的详细信息,如构造函数、成员变量和成员函数等。
2 获取字节码文件
首先,构造一个实体类:
/** * @Author Charies Guo * @Date 2017/7/29,下午5:15 * @Description Person Entity */public class Person { private String name; private int age; public Person() { System.out.println("Person run"); } public Person(String name, int age) { this.name = name; this.age = age; System.out.println("Person param run ... " + this.name + " is " + this.age + " years old!"); } public void showInfo(String name, int age){ this.name = name; this.age = age; System.out.println("Show Peron Info : " + this.name + " is " + this.age + " years old!"); } public void playBadminton(){ System.out.println("Let's play badminton, go go go..."); }}
接下来,以 Person 类为例,演示获取字节码文件的 3 种方式:
/** * @Author Charies Guo * @Date 2017/7/29,下午5:23 * @Description Get class file */public class GetClassFile { public static void main(String[] args) throws ClassNotFoundException { System.out.println("第 1 种获取方式:"); getClassObject_1(); System.out.println("第 2 种获取方式:"); getClassObject_2(); System.out.println("第 3 种获取方式:"); getClassObject_3(); } /** * 利用 Object 类中的 getClass 方法 * 用这个方法时,必须明确具体的类,并创建对象 * 比较麻烦 */ public static void getClassObject_1() { Person p = new Person(); Class clazz = p.getClass(); Person p1 = new Person("Charies",18); Class clazz1 = p1.getClass(); System.out.println(clazz == clazz1); } /** * 任何数据类型都具备一个静态属性 * 通过 .class 来获取对应的 Class 对象 * 扩展性较差 */ public static void getClassObject_2() { Class clazz = Person.class; Class clazz1 = Person.class; System.out.println(clazz == clazz1); } /** * 通过给定的类的字符串名称就可以获取该类的字节码文件,更利于扩展 * 可以用 Class 类中的 forName() 方法来完成 */ public static void getClassObject_3() throws ClassNotFoundException { // 包名一定要写全,否则会报 java.lang.ClassNotFoundException 异常 String className = "Person"; Class clazz = Class.forName(className); System.out.println(clazz); }}
执行上述代码,结果如下图所示:
3 获取字节码文件的内容
3.1 获取构造函数
import java.lang.reflect.Constructor;/** * @Author Charies Guo * @Date 2017/7/29,下午6:07 * @Description Get class constructor */public class GetClassConstructor { public static void main(String[] args) throws Exception { createNewObject_1(); createNewObject_2(); } /** * 获取默认构造函数 */ public static void createNewObject_1() throws ClassNotFoundException, InstantiationException, IllegalAccessException { String name = "Person"; // 寻找该名称类文件,并加进内存,产生 Class 对象 Class clazz = Class.forName(name); // 产生该类的实例对象(空参) Object obj = clazz.newInstance(); } /** * 获取带参数的构造函数 */ public static void createNewObject_2() throws Exception { /** * 当获取指定名称对应类中的实体对象时,而且该对象的初始化不适用空参的构造函数 * 可以先通过该类的字节码文件对象,获取空参的构造函数 * 该方法为:getConstructor(parameterTypes) */ // 包名一定要写全,否则会报 java.lang.ClassNotFoundException 异常 String name = "Person"; // 找寻该名称类文件,并加进内存,产生 Class 对象 Class clazz = Class.forName(name); // 获取指定的构造函数对象 Constructor constructor = clazz.getConstructor(String.class, int.class); // 通过该构造器对象的 newInstance 方法进行对象的初始化 constructor.newInstance("Charies", 18); }}
3.2 获取成员变量
import java.lang.reflect.Field;/** * @Author Charies Guo * @Date 2017/7/29,下午6:15 * @Description Get class field */public class GetClassField { public static void main(String[] args) throws Exception { getField(); } /** * 获取字节码文件中的成员变量 */ public static void getField() throws Exception { Class clazz = Class.forName("Person"); Field field = null; // 获取本类字段,包含私有 field = clazz.getDeclaredField("age"); // 对私有字段的访问取消权限检查,可称之为暴力访问 field.setAccessible(true); Object obj = clazz.newInstance(); field.set(obj, Integer.valueOf(18)); Object o = field.get(obj); System.out.println(o); }}
3.3 获取成员函数
import java.lang.reflect.Constructor;import java.lang.reflect.Method;/** * @Author Charies Guo * @Date 2017/7/29,下午6:22 * @Description Get class method */public class GetClassMethod { public static void main(String[] args) throws Exception { System.out.println("第 1 个方法:"); getMethod_1(); // System.out.println("第 2 个方法:"); // getMethod_2(); // System.out.println("第 3 个方法:"); // getMethod_3(); } /** * 获取指定 Class 中的公有函数 */ public static void getMethod_1() throws Exception { Class clazz = Class.forName("Person"); // 获取的都是类中的公有方法 Method[] methods = clazz.getMethods(); // 获取本类中的所有方法 methods = clazz.getDeclaredMethods(); Method[] var5 = methods; int var4 = methods.length; for (int var3 = 0; var3 < var4; ++var3) { Method method = var5[var3]; System.out.println(method); } } /** * 获取指定 Class 中的空参函数 */ public static void getMethod_2() throws Exception { Class clazz = Class.forName("Person"); // 获取空参数的方法 Method method = clazz.getMethod("playBadminton"); Constructor constructor = clazz.getConstructor(new Class[]{String.class, Integer.TYPE}); Object obj = constructor.newInstance(new Object[]{"Charies", Integer.valueOf(18)}); method.invoke(obj, (Object[]) null); } /** * Integer.TYPE 等价于 int.class */ public static void getMethod_3() throws Exception { Class clazz = Class.forName("Person"); Method method = clazz.getMethod("showInfo", new Class[]{String.class, Integer.TYPE}); Object obj = clazz.newInstance(); method.invoke(obj, new Object[]{"Charies", Integer.valueOf(18)}); }}
阅读全文
1 0
- 详述获取字节码文件及其内容的方法
- 获取类字节码文件 .class 文件的3种方法
- 获取字节码文件的相关内容
- 详述Windows 2000的日志及其删除方法
- 文件路径及其文件名内容获取
- 从指定文件(字节数组)获取内容以及获取长度
- java获取对应字节数的内容
- 《黑马程序员》 使用反射获取字节码文件中的方法
- 使用反射获取字节码文件中的方法
- 反射(reflect)--获取字节码文件中的方法(函数)
- 获取文件的字节数
- linux获取文件的路径名及其文件名的方法
- 读取文件字节流的方法及某些时候读取不到文件内容的疑问
- seek和tell的用法--获取文件内容大小(字节)
- 二.PCM(44字节)的Wav文件头及其相关的编程方法
- PCM(44字节)的Wav文件头及其相关的编程方法
- PCM(44字节)的Wav文件头及其相关的编程方法
- PHP中获取某个网页或文件内容的方法
- 输出今天的日期,以YYYY-MM-DD的方式,比如今天是2017年7月29日,则输出2017-07-29
- Android_Manager:PackageManager
- Path Sum
- HDU 6035 Colorful Tree(树形DP)
- Set 不重复实现原理
- 详述获取字节码文件及其内容的方法
- LintCode python 小白-简单题-22平面列表
- poj 3683 2SAT入门+挑战模板
- 《Drools7.0.0.Final规则引擎教程》第4章 4.4 LHS简介&Pattern
- 冒泡排序、插入排序和选择排序
- 百度、腾讯和阿里内部的级别和薪资待遇是什么样的?
- 高并发的核心技术-幂等的实现方案
- 原生js实现检测对象变化
- 基于Nsight Eclipse Edition的高斯滤波的实现(一)