class类

image.png

反射的功能

image.png

获取Class类

image.png

代码

  1. // 方式一通过getClass
  2. Class cc1=u1.getClass();
  3. // 方式二通过包名
  4. Class cc2=Class.forName("com.fu.bean.user");
  5. // 方式三通过类命.class
  6. Class cc3=user.class;
  7. // 方式四基本内置类型都有一个type属性 可以返回class
  8. Class cc4=String.class;
  9. // 方式五 获得父类的class
  10. Class cc4=c1.getSuperclass();

什么类型有class对象

image.png

  1. Class c1=Object.class;//对象
  2. Class c2= Serializable.class;//接口
  3. Class c3=String[].class;//数组
  4. Class c4=int[][].class;//二维数组
  5. Class c5=Test.class;//注解
  6. Class c6=int.class;//基本类型
  7. Class c7=void.class;//void
  8. Class c8=Class.class;//class

java内存分析

image.png

类的加载过程

image.png

类加载器

BootstrapClassLoader(启动类加载器)

c++编写,加载java核心库 java.*,构造ExtClassLoaderAppClassLoader。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作

ExtClassLoader (标准扩展类加载器)

java编写,加载扩展库,如classpath中的jrejavax.*或者
java.ext.dir 指定位置中的类,开发者可以直接使用标准扩展类加载器。

AppClassLoader(系统类加载器)

java编写,加载程序所在的目录,如user.dir所在的位置的class

CustomClassLoader(用户自定义类加载器)

java编写,用户自定义的类加载器,可加载指定路径的class文件

源码分析

  1. protected Class<?> loadClass(String name, boolean resolve)
  2. throws ClassNotFoundException
  3. {
  4. synchronized (getClassLoadingLock(name)) {
  5. // 首先检查这个classsh是否已经加载过了
  6. Class<?> c = findLoadedClass(name);
  7. if (c == null) {
  8. long t0 = System.nanoTime();
  9. try {
  10. // c==null表示没有加载,如果有父类的加载器则让父类加载器加载
  11. if (parent != null) {
  12. c = parent.loadClass(name, false);
  13. } else {
  14. //如果父类的加载器为空 则说明递归到bootStrapClassloader了
  15. //bootStrapClassloader比较特殊无法通过get获取
  16. c = findBootstrapClassOrNull(name);
  17. }
  18. } catch (ClassNotFoundException e) {}
  19. if (c == null) {
  20. //如果bootstrapClassLoader 仍然没有加载过,则递归回来,尝试自己去加载class
  21. long t1 = System.nanoTime();
  22. c = findClass(name);
  23. sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
  24. sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
  25. sun.misc.PerfCounter.getFindClasses().increment();
  26. }
  27. }
  28. if (resolve) {
  29. resolveClass(c);
  30. }
  31. return c;
  32. }
  33. }

双亲委派机制

反射机制 - 图7

通过反射获得构造器、方法、属性等

  1. Class c1=Class.forName("com.fu.bean.user");
  2. System.out.println(c1.getName());// get package name and class name
  3. System.out.println(c1.getSimpleName()); // get class name
  4. Field[] fields = c1.getFields();// only can find public attributes
  5. for (Field field : fields) {
  6. System.out.println(field);
  7. }
  8. fields=c1.getDeclaredFields();//can find all attributes
  9. for (Field field : fields) {
  10. System.out.println(field);
  11. }
  12. //Gets a public specified property
  13. // Field name=c1.getField("name");
  14. // System.out.println(name);
  15. // Gets a specified property
  16. Field name=c1.getDeclaredField("name");
  17. System.out.println(name);
  18. System.out.println("======================");
  19. Method[] method = c1.getMethods();//找到本类和父类的全部的public的方法
  20. for (Method method1 : method) {
  21. System.out.println(method1);
  22. }
  23. System.out.println("======================");
  24. Method[] declaredMethods = c1.getDeclaredMethods();//找到本类的全部方法
  25. for (Method declaredMethod : declaredMethods) {
  26. System.out.println(declaredMethod);
  27. }
  28. System.out.println("======================");
  29. //获得指定方法
  30. Method m1=c1.getMethod("getName");
  31. System.out.println(m1);
  32. Method m2=c1.getDeclaredMethod("setAge", int.class);
  33. System.out.println(m2);
  34. System.out.println("======================");
  35. //获得全部构造器
  36. Constructor[] con=c1.getConstructors();
  37. for (Constructor constructor : con) {
  38. System.out.println(constructor);
  39. }
  40. System.out.println("======================");
  41. Constructor[] con2=c1.getDeclaredConstructors();
  42. for (Constructor constructor : con2) {
  43. System.out.println(constructor);
  44. }
  45. System.out.println("======================");
  46. //获得指定构造器
  47. Constructor conn=c1.getConstructor(String.class,int.class);
  48. System.out.println(conn);
  49. System.out.println("======================");
  50. // invoke (调用)激活(参数1:对象名,参数2:值) 通过反射得到的方法调用
  51. user uu1= (user) c1.newInstance();
  52. Method setName = c1.getMethod("setName", String.class);
  53. setName.invoke(uu1,"fdy");
  54. System.out.println(uu1.getName());
  55. System.out.println("======================");
  56. // 不可能直接对private的field属性用set方法,需要使用setAccessible()破解权限
  57. user uu2= (user) c1.newInstance();
  58. Field age = c1.getDeclaredField("age");
  59. age.setAccessible(true);
  60. age.set(uu2,18);
  61. System.out.println(uu2.getAge());

tips

如果需要频繁调用反射, 可以把 检测关闭了setAccessible(true)

获取泛型消息

  1. public class test05 {
  2. public void tese01(Map<String,Integer> map, List<Double> list){
  3. System.out.println(233);
  4. }
  5. public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
  6. Class test05 = Class.forName("test05");
  7. Method tese01 = test05.getMethod("tese01", Map.class, List.class);
  8. Type[] genericParameterTypes = tese01.getGenericParameterTypes();
  9. for (Type genericParameterType : genericParameterTypes) {
  10. System.out.println(genericParameterType);
  11. if(genericParameterType instanceof ParameterizedType){
  12. Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
  13. for (Type actualTypeArgument : actualTypeArguments) {
  14. System.out.println(actualTypeArgument);
  15. }
  16. }
  17. }
  18. }
  19. }