类加载&类加载器
类的加载描述:
反射&reflect
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
-
Class类的获取
/*for example*/ public class TestClass { public static void main(String[] args) throws ClassNotFoundException { /* 类的三种获取方式 */ /* the first... */ Person p = new Person(); Class pClass = p.getClass(); System.out.println(pClass); /* the second... */ Class sClass = Person.class; System.out.println(sClass); /* the third... */ Class tClass = Class.forName("ReflectionTools.Person"); System.out.println(tClass); } }
-
Class类构造方法的获取
/*for example*/ /* 仅仅显示由public修饰的构造方法 */ Constructor[] con = tClass.getConstructors(); for (Object obj : con) System.out.println(obj); Constructor[] conAll = tClass.getDeclaredConstructors(); System.out.println("------- this is a dividing line --------"); /* 所有的构造方法都显示出来. */ for (Object obj : conAll) System.out.println(obj); System.out.println("------- this is a dividing line --------");
-
Class类字段的获取
/*for example*/ 与构造方法完全一样,用Field替换对应的部分即可。
-
Class类成员方法的获取
/*for example*/ 不同之处在于getMethods方法获取的是获取的所有方法,包括父类的的public修饰的。 getDeclaredMethods是自己的所有修饰符修饰的成员方法。
-
使用带Declared的函数获取的函数是完整的,但是若需要使用指定的成员变量与成员方法,则可以利用反射。使用对应的带参数的函数+函数名称即可调用,若是非公有的,可以使用setAccessiable強制調用。
/*for example 非局部的使用*/ /*PJO定义一个简单的类*/ package ReflectionTools; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; class Person { private String name; private int age; private String address; /* 私有的带参构造方法。 */ private Person(String name, int age) { this.name = name; this.age = age; } public Person(String name) { this.name = name; } public Person(String name, int age, String address) { super(); this.name = name; this.age = age; this.address = address; } /* 无参构造方法. */ Person() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } private void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; } } /*测试主函数*/ public class TestClass { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException { /* 类的三种获取方式 */ /* the first... */ Person p = new Person(); Class pClass = p.getClass(); System.out.println(pClass); /* the second... */ Class sClass = Person.class; System.out.println(sClass); /* the third... */ Class tClass = Class.forName("ReflectionTools.Person"); System.out.println(tClass); System.out.println("-------this is a dividing line--------"); /* 仅仅显示由public修饰的构造方法 */ Constructor[] con = tClass.getConstructors(); for (Object obj : con) System.out.println(obj); Constructor[] conAll = tClass.getDeclaredConstructors(); System.out.println("------- this is a dividing line --------"); /* 所有的构造方法都显示出来. */ for (Object obj : conAll) System.out.println(obj); System.out.println("------- this is a dividing line --------"); /* 无参数构造方法的使用。 */ Constructor conSpecific = tClass.getDeclaredConstructor(); Object obj = conSpecific.newInstance(); /*调用private修饰的变量*/ Field fieldSpecific = tClass.getDeclaredField("name"); fieldSpecific.setAccessible(true); fieldSpecific.set(obj, "Tom"); /* 调用非public修饰的成员方法 */ Method methodSpecific = tClass.getDeclaredMethod("setAge", int.class); methodSpecific.setAccessible(true); methodSpecific.invoke(obj, 5); System.out.println(obj); } } /*控制台输出结果为:*/ class ReflectionTools.Person class ReflectionTools.Person class ReflectionTools.Person -------this is a dividing line-------- public ReflectionTools.Person(java.lang.String,int,java.lang.String) public ReflectionTools.Person(java.lang.String) ------- this is a dividing line -------- private ReflectionTools.Person(java.lang.String,int) ReflectionTools.Person() public ReflectionTools.Person(java.lang.String,int,java.lang.String) public ReflectionTools.Person(java.lang.String) ------- this is a dividing line -------- Person [name=Tom, age=5, address=null]
-
反射的应用
-
构造一个动态的对象调用动态的方法:
/*for example*/ /**config.ini是配置class类和对应方法的。/ package ReflectionTools; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; /*config.ini*/ /*content: className = ReflectionTools.personTest classValue = hobby */ class animal { private String name; public animal() { } public void show() { System.out.println(this.name + "this is animailShow!"); } } class personTest { private String name; private int age; private String address; public personTest() { } public void hobby() { System.out.println(this.name + "this is a personHobby!" + this.age + this.address); } } public class ReflectionApp { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { /* 使用throws不必初始化,直接异常弹出,这样的目的是为了防止空指针异常。 */ FileReader fileReader = new FileReader("config.ini"); Properties keyValue = new Properties(); keyValue.load(fileReader); fileReader.close(); String getNameID = keyValue.getProperty("className"); String getValueID = keyValue.getProperty("classValue"); Class classFiles = Class.forName(getNameID); Constructor con = classFiles.getConstructor(); Object obj = con.newInstance(); Method meTest = classFiles.getDeclaredMethod(getValueID); meTest.invoke(obj); } }
-
反射修改泛型
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; /* * 我给你ArrayList<Integer>的一个对象,要求在这个集合中添加一个字符串数据。 */ public class ArrayLis{ public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { /*创建集合对象*/ ArrayList<Integer> array = new ArrayList<Integer>(); Class classfile = array.getClass(); /*集合ArrayList的class文件对象*/ Method me = classfile.getMethod("add", Object.class); me.invoke(array, "hello"); /*调用array的add方法,传入的值是hello.*/ me.invoke(array, "world"); System.out.println(array); } }
-
-
Proxy代理对象
- 描述:代理一个对象的操作,结合InvocationHandler接口,只能实现对接口的代理。若要对类进行代理需要使用cglib。
- tip:该类代理不会再框架中使用,故而略…