【参考资料: 疯狂Java讲义 Chapter 18】java
一、类加载、链接、初始化数组
当Java程序须要某一个类时,若是该类还没有加载到内存中,系统会经过加载、链接、初始化三个步骤将该类加载到内存,并完成初始化工做。函数
二、类加载器spa
JVM启动时,会造成由三个类加载器类组成的初始类的加载器层次结构:code
三个类加载器之间的层次关系:component
三、经过反射操做类对象
1)获取java.lang.Class对象的经常使用方式blog
2)Class类提供的接口继承
获取Class对象所对应类的构造器的接口:接口
1 Constructor<T> getConstructor(Class<?>... parameterTypes) //返回对应该类的public的构造器,构造器参数列表的类型声明次序符合parameterTypes类型声明次序,被封装成了Constructor对象 2 Constructor<?>[] getConstructors() //获取全部public构造器 3 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) //返回对应parameterTypes类型声明次序的该类的构造器,与访问级别无关 4 Constructor<?>[] getDeclaredConstructors()//返回全部的构造器,与访问级别无关
5 Constructor<?> getEnclosingConstructor() //用于匿名类或内部类
获取Class对象对应类的方法的接口:
1 Method getMethod(String name, Class<?>... parameterTypes); //返回由方法名name和参数列表类型parameterTypes限定的public方法 2 Method[] getMethods(); //全部public方法 3 Method getDeclaredMethod(String name, Class<?>... parameterTypes); //返回由方法名和参数列表类型parameterTypes限定的方法,与访问级别无关 4 Method[] getDeclaredMethods(); //全部方法
5 Method getEnclosingMethod(); //用于获取内部类或匿名类的方法
获取Class对象对应类所包含的属性的接口:
1 Field getField(String name); //返回对应name的public 属性 2 Field[] getFields(); //全部public属性 3 Field getDeclaredField(String name); 4 Field[] getDeclaredFields();
【注:方法名中带有Declared的方法返回的构造器、方法或属性等都是忽略访问级别的;而不带有Declared的方法返回public的类成员。】
访问Class对应类的注释的接口:
1 <A extends Annotation> A getAnnotation(Class<A> annotationClass); //返回符合特定注解类型annotationClass的注解 2 Annotation[] getAnnotations(); //当前Class的全部注解 3 Annotation[] getDeclaredAnnotations(); //直接出如今当前元素上的注解
Class中用于判断该Class是否为注释类型、数组类型、接口类型的接口:
1 boolean isAnnotation(); 2 boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); //判断是否出现了特定类型的注解 3 boolean isAnonymousClass(); 4 boolean isArray(); 5 boolean isEnum(); 6 boolean isInstance(Object obj); //判断obj类型是否与当前Class对应的类型兼容 7 boolean isInterface(); 8 boolean isLocalClass(); 9 boolean isPrimitive();
其余接口:
1 String getName();//返回该Class表明的类或接口的全称 2 String getPackage(); //返回包名 3 String getSimpleName(); //Class对应类的简称 4 Class<? super T> getSuperclass(); //返回超类
对于上述接口中出现的Class<?>... parameterTypes,是指定的参数列表的Class对象。如:
1 public class ReflectionTest{ 2 3 private int privateAttribute = -1; 4 public int publicAttribute = -2; 5 6 public String publicStrAttribute = "DefaultString"; 7 8 9 public void info(){ 10 System.out.println("This is info() of class ReflectionTest"); 11 } 12 13 public void info(String str){ 14 System.out.println("This is info(String) of class ReflectionTest"); 15 } 16 17 public void info(String str, Integer num){ 18 System.out.println("This is info(String, Integer) of class ReflectionTest"); 19 } 20 21 private void privateInfo(){ 22 System.out.println("This is privateInfo method"); 23 } 24 25 public static void main(String[] args) throws Exception{ 26 Class<ReflectionTest> testClass = ReflectionTest.class; 27 28 Method info1 = testClass.getMethod("info", null); 29 System.out.println("方法参数列表长度: "+info1.getParameterTypes().length); 30 31 Method info2 = testClass.getMethod("info", String.class); 32 System.out.println("方法参数列表长度: "+info2.getParameterTypes().length); 33 34 Method info3 = testClass.getMethod("info", String.class, Integer.class); 35 System.out.println("方法参数列表长度: "+info3.getParameterTypes().length); 36 } 37 }
3)经过反射生成并操做对象
1 Class<ReflectionTest> testClass = ReflectionTest.class; 2 3 //经过Class对象构造Class对应类的实例 4 ReflectionTest rt1 = testClass.newInstance(); 5 Constructor constructor = testClass.getConstructor(null); 6 ReflectionTest rt2 = (ReflectionTest)constructor.newInstance(null); //调用默认构造函数,参数列表为空
【注:代码基于ReflectionTest类】
4)调用方法
1 Object newTest = constructor.newInstance(null); 2 Method info = testClass.getMethod("info", null); 3 info.invoke(newTest, null);
而后调用private方法:
1 Method privateMethod = testClass.getDeclaredMethod("privateInfo", null); //获取private方法使用getDeclaredMethod方法 2 privateMethod.setAccessible(true); 3 privateMethod.invoke(newTest, null);
5)操做属性值
1 //操做属性 2 Field privateField = testClass.getDeclaredField("privateAttribute"); //私有属性 3 System.out.println(privateField.getInt(newTest)); 4 privateField.setInt(newTest, -1000); 5 System.out.println(privateField.get(newTest)); 6 7 Field strField = testClass.getField("publicStrAttribute"); //公有属性 8 System.out.println(strField.get(newTest)); 9 strField.set(newTest, "test value"); 10 System.out.println(strField.get(newTest));
6)操做数组
java.lang.reflect包下含有Array类,Array类提供了能够动态建立和访问Java数组的静态方法。
主要接口:
1 static static Object newInstance(Class<?> componentType, int... dimensions); //多维度的数组 2 static Object newInstance(Class<?> componentType, int length); //指定数组长度的数组 3 4 static XXX getXXX(Object array, int index); //对于8中基本类型 5 static void setXXX(Object array, int index, XXX newValue); 6 7 static Object get(Object array, int index); //对于引用类型 8 static void setXXX(Object array, int index, Object newValue);