class类
反射的功能
获取Class类
代码
// 方式一通过getClassClass cc1=u1.getClass();// 方式二通过包名Class cc2=Class.forName("com.fu.bean.user");// 方式三通过类命.classClass cc3=user.class;// 方式四基本内置类型都有一个type属性 可以返回classClass cc4=String.class;// 方式五 获得父类的classClass cc4=c1.getSuperclass();
什么类型有class对象

Class c1=Object.class;//对象Class c2= Serializable.class;//接口Class c3=String[].class;//数组Class c4=int[][].class;//二维数组Class c5=Test.class;//注解Class c6=int.class;//基本类型Class c7=void.class;//voidClass c8=Class.class;//class
java内存分析
类的加载过程
类加载器
BootstrapClassLoader(启动类加载器)
c++编写,加载java核心库 java.*,构造ExtClassLoader和AppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作
ExtClassLoader (标准扩展类加载器)
java编写,加载扩展库,如classpath中的jre ,javax.*或者java.ext.dir 指定位置中的类,开发者可以直接使用标准扩展类加载器。
AppClassLoader(系统类加载器)
java编写,加载程序所在的目录,如user.dir所在的位置的class
CustomClassLoader(用户自定义类加载器)
java编写,用户自定义的类加载器,可加载指定路径的class文件
源码分析
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// 首先检查这个classsh是否已经加载过了Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {// c==null表示没有加载,如果有父类的加载器则让父类加载器加载if (parent != null) {c = parent.loadClass(name, false);} else {//如果父类的加载器为空 则说明递归到bootStrapClassloader了//bootStrapClassloader比较特殊无法通过get获取c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {}if (c == null) {//如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载classlong t1 = System.nanoTime();c = findClass(name);sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}
双亲委派机制
通过反射获得构造器、方法、属性等
Class c1=Class.forName("com.fu.bean.user");System.out.println(c1.getName());// get package name and class nameSystem.out.println(c1.getSimpleName()); // get class nameField[] fields = c1.getFields();// only can find public attributesfor (Field field : fields) {System.out.println(field);}fields=c1.getDeclaredFields();//can find all attributesfor (Field field : fields) {System.out.println(field);}//Gets a public specified property// Field name=c1.getField("name");// System.out.println(name);// Gets a specified propertyField name=c1.getDeclaredField("name");System.out.println(name);System.out.println("======================");Method[] method = c1.getMethods();//找到本类和父类的全部的public的方法for (Method method1 : method) {System.out.println(method1);}System.out.println("======================");Method[] declaredMethods = c1.getDeclaredMethods();//找到本类的全部方法for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}System.out.println("======================");//获得指定方法Method m1=c1.getMethod("getName");System.out.println(m1);Method m2=c1.getDeclaredMethod("setAge", int.class);System.out.println(m2);System.out.println("======================");//获得全部构造器Constructor[] con=c1.getConstructors();for (Constructor constructor : con) {System.out.println(constructor);}System.out.println("======================");Constructor[] con2=c1.getDeclaredConstructors();for (Constructor constructor : con2) {System.out.println(constructor);}System.out.println("======================");//获得指定构造器Constructor conn=c1.getConstructor(String.class,int.class);System.out.println(conn);System.out.println("======================");// invoke (调用)激活(参数1:对象名,参数2:值) 通过反射得到的方法调用user uu1= (user) c1.newInstance();Method setName = c1.getMethod("setName", String.class);setName.invoke(uu1,"fdy");System.out.println(uu1.getName());System.out.println("======================");// 不可能直接对private的field属性用set方法,需要使用setAccessible()破解权限user uu2= (user) c1.newInstance();Field age = c1.getDeclaredField("age");age.setAccessible(true);age.set(uu2,18);System.out.println(uu2.getAge());
tips
如果需要频繁调用反射, 可以把 检测关闭了setAccessible(true)
获取泛型消息
public class test05 {public void tese01(Map<String,Integer> map, List<Double> list){System.out.println(233);}public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class test05 = Class.forName("test05");Method tese01 = test05.getMethod("tese01", Map.class, List.class);Type[] genericParameterTypes = tese01.getGenericParameterTypes();for (Type genericParameterType : genericParameterTypes) {System.out.println(genericParameterType);if(genericParameterType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}}}}
