类型信息 运行时类型信息,能够在程序运行时发现和使用类型信息。
Class对象 Class对象用来表示运行时的类型信息。
类是程序的一部分, 每个类都有一个Class对象。 被保存在一个同名的.class文件中。 为了生产这个类的对象, JVM会先调用“类加载器”子系统来把这个类加载到内存中。
类加载器子系统可能包含一条类加载器链, 但是有且只有一个原生类加载器。 它是JVM实现的一部分,通常在这条链中,不需要添加额外的类加载器,但是如果有特殊需要, (比如以某种特殊的方式加载类,以支持web服务器应用,或者网络下载类。可以以挂载其他额外的类加载器。)
当程序创建一个类的静态成员时, 就会加载这个类。 (构造函数就是静态的,只是省略了static)
类加载器首先会检查这个类的Class对象有没有加载,如果没有, 就会根据类名加载.class文件。 JVM会对加载后的字节码进行验证,确保没有损坏
反射 Java不允许在运行时改变程序结构或类型变量的结构, 但是它允许在运行时探知、加载、调用在编译期完全未知的class, 可以在运行时加载class, 生成实例对象, 嗲用method , 或者field赋值。
这种类似于看透了class的特性称为反射。在java.lang.reflect库中包含类Field、Method和Constructor。对应了成员变量, 方法, 和构造方法
动态代理 代理是基本的设计模式之一。 一个对象封装真实的对象, 代替其提供其他或者不同的操作, 这些操作通常涉及与真实对象的通信, 代理对象通常作为中间对象。
Java的动态代理, 不仅动态创建代理对象, 而且动态处理对代理方法的调用。 在动态代理上进行的所有调用都被重定向到单个调用处理程序, 该处理程序负责发现调用内容并决定如何处理。
JDK动态代理 使用JDK动态代理的基本步骤
通过实现InvocationHandler接口来定义一个自己的调用处理器
通过Proxy.newProxyInstance获得代理对象
通过代理对象调用目标方法
JDK动态代理源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 public static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null ) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } Class<?> cl = getProxyClass0(loader, intfs); try { if (sm != null ) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run () { cons.setAccessible(true ); return null ; } }); } return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }
代理类的生成方法getProxyClass0(loader, intfs);
1 2 3 4 5 6 7 8 private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { if (interfaces.length > 65535 ) { throw new IllegalArgumentException("interface limit exceeded" ); } return proxyClassCache.get(loader, interfaces); }
1 2 3 4 5 6 7 8 9 10 11 12 public V get (K key, P parameter) { ... ... ... Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter)); ... ... ... }
ProxyClassFactory的apply()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { ... ... ... byte [] proxyClassFile = ProxyGenerator.generateProxyClass( proxyName, interfaces, accessFlags); try { return defineClass0(loader, proxyName, proxyClassFile, 0 , proxyClassFile.length); } catch (ClassFormatError e) { throw new IllegalArgumentException(e.toString()); } ... ... ... }
进入generateProxyClass()又调用了proxyGenerator.generateClassFile();
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 private byte [] generateClassFile() { this .addProxyMethod(hashCodeMethod, Object.class); this .addProxyMethod(equalsMethod, Object.class); this .addProxyMethod(toStringMethod, Object.class); Class[] var1 = this .interfaces; int var2 = var1.length; int var3; Class var4; for (var3 = 0 ; var3 < var2; ++var3) { var4 = var1[var3]; Method[] var5 = var4.getMethods(); int var6 = var5.length; for (int var7 = 0 ; var7 < var6; ++var7) { Method var8 = var5[var7]; this .addProxyMethod(var8, var4); } } Iterator var11 = this .proxyMethods.values().iterator(); List var12; while (var11.hasNext()) { var12 = (List)var11.next(); checkReturnTypes(var12); } Iterator var15; try { this .methods.add(this .generateConstructor()); var11 = this .proxyMethods.values().iterator(); while (var11.hasNext()) { var12 = (List)var11.next(); var15 = var12.iterator(); while (var15.hasNext()) { ProxyGenerator.ProxyMethod var16 = (ProxyGenerator.ProxyMethod)var15.next(); this .fields.add(new ProxyGenerator.FieldInfo(var16.methodFieldName, "Ljava/lang/reflect/Method;" , 10 )); this .methods.add(var16.generateMethod()); } } this .methods.add(this .generateStaticInitializer()); } catch (IOException var10) { throw new InternalError("unexpected I/O Exception" , var10); } ... ... ... }
Optional类 当操作的对象是null时, 会产生NullPointException异常。 Optional对象可以防止代码抛出空指针的异常
Anything can go right will go right