370 likes | 575 Views
Java 培训. 高级语言特性. Java 类加载运行的三个步骤 Loading Linking Initializing. Class Loader. 类加载器 按需加载 Class 系统类加载器结构 bootstrap classloader ( Native ) | extension classloader | system classloader 委托关系. Class Loader. JVM 中 Class 的标识 ClassLoader + Class
E N D
Java 培训 高级语言特性
Java 类加载运行的三个步骤 • Loading • Linking • Initializing ClassLoader
类加载器 • 按需加载 Class • 系统类加载器结构 bootstrap classloader(Native) | extension classloader | system classloader • 委托关系 ClassLoader
JVM中Class的标识 • ClassLoader+Class • 解释不同加载器加载同一Class得到不同类型的原因 • JEE Web Application’s ClassLoader • 优先加载自己所在上下文路径下的类 • 可能产生隐患 ClassLoader
类加载与代码热更新 • 代码热更新的原理 • 副作用带来的困难 • 内存泄漏的隐患 ClassLoader
OSGI与类加载 • 网状ClassLoader结构(重载loadClass) • 每个Bundle的类由Bundle对应的ClassLoader加载 ClassLoader
JavaSE7 对 ClassLoader 的改进 • 解决非传统层级结构模式下,并行类加载的死锁问题 Eg: A:B lock(CL1)lock(CL2) C:Dlock(CL2)lock(CL1) ClassLoader
Annotation的用途 • 配置信息 • 元信息增强 • 定义DSL(AspectJ) Annotation
如何定义Annotation import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { String name() default “undefined” } Annotation
@Retention • RetentionPolicy.RUNTIME • RetentionPolicy.CLASS • RetentionPolicy.SOURCE • @Target • ElementType{TYPE, FIELD, METHOD, PARAMETER,CONSTRUCTOR, LOCAL_VARIBLE, ANNOTATION_TYPE, PACKAGE, TYPE} • 特殊的Target: Package,只能用于package-info.java Annotation
@Inherited • Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect. Annotation
@Documented • 将被文档化 • 仅当annotation对所作用的元素的使用产生影响,且该元素对用户公开时使用 Annotation
Standard Annotations • @Deprecated • @Override • @SuppressWarnings Annotation
Annotation 的其他应用场合 • REST(JSR311) @Path("widgets") public class WidgetsResource { @GET @Path("offers") public WidgetListgetDiscounted() {...} @Path("{id}") public WidgetResourcefindWidget(@PathParam("id") String id) { return new WidgetResource(id); } } Annotation
Integration Test @TestCaseInfo( username = “John”, mail = “john@abc.com” ) public class MyTestCase{ … } • 其他:各类Frameworks,Spring,EJBetc …… Annotation
ReflectionAPIs • 以Method为例 • public Annotation[] getDeclaredAnnotations() • public Annotation[][] getParameterAnnotations() • 访问Annotaion成员 UserDefinedAnnotation a; …. //read a String attribute1 = a.attribute1(); • 当Retetion为CLASS则需要使用理解class格式的工具如ASM Annotation
为何引入泛型 • 集合类的类型缺陷,通过引入泛型弥补 • 消除强制类型转换 • Java泛型 VS C++泛型 • C++:templates • Java:type enhancement • 泛型信息仅存在于Source与Class文件中,运行时会被擦除(该方案无需修改JVM) Generic
泛型的使用 • 泛型类型的定义 • public interface Map<K, V> { public void put(K key, V value); public V get(K key); } • 定义泛型常用名称 • * K —— 键,比如映射的键。 * V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。 * E —— 异常类。 * T —— 泛型。 Generic
实例化泛型类型 • Map<String, String> m = new HashMap<String, String>(); m.put("key", “value0"); String s = m.get("key"); • 泛型不可协变 • List<Integer> intList = new ArrayList<Integer>(); List<Number> numberList = intList; // invalid • 泛型通配符 • List<?> list = new ArrayList<Integer>(); • 类型推断 • list.get(0); //返回值经类型推断为Object • 通配符捕获, 产生类型占位符 • foo(Pair<?,?> x, Pair<?,?> y) • 类型限制 • public class Matrix<V extends Number> { ... } Generic
Java SE 7对泛型的改进 • 实例化时的类型推断 • OLD • List<String> list = newArrayList<String>(); • NEW • List<String> list = newArrayList<>(); Generic
类型识别 • instanceof • downcasting The Java RTTI mechanism allows you to discover an objects type at run time. However: it requires full knowledge of the needed types at compile time. RTTI & Reflection
Reflection • 自省(introspection) • 在运行时自省与对象关联的类的元数据(metadata) • 基于自省的元数据提供的一系列运行时的能力构成了Java的反射机制。 RTTI & Reflection
Reflection 用途 • 访问Method, Field • Class ownerClass = owner.getClass(); Field field = ownerClass.getField(fieldName); Object property = field.get(owner); ------------------------------------------------------------ Class ownerClass = owner.getClass(); Class[] argsClass = ...; Object[] args = ...; Method method = ownerClass.getMethod(methodName, argsClass); method.invoke(owner, args); RTTI & Reflection
构造对象 Class newoneClass = Class.forName(className); Class[] argsClass = ...; Object[] args = ...; Constructor cons = newoneClass.getConstructor(argsClass); cons.newInstance(args); RTTI & Reflection
动态代理 • handler = new InvocationHandlerImpl(..); Interface proxy = (Interface)Proxy.newProxyInstance( classLoader, new Class[] { Interface.class }, handler ); • 大量用于Spring AOP的实现 • 限制:只能基于Interface RTTI & Reflection
Call Stack自省 RTTI & Reflection
Reflection 性能 • 虚拟机层面的优化 • Bytecode stub generation • 当前的主要开销 • 处理参数(区别于invoke dynamic) • 结论:除了在动态语言这样密集调用reflection的环境下,通常不会成为性能的瓶颈。 RTTI & Reflection
Reflection的局限 • 只能利用元数据进行只读的访问或调用,无法改变类的行为。 • 动态代理通过接口的代理能在某种程度上达到改变类的行为的目的,但仍不够灵活。 • 解决方法 • Code Generation • ASM • Javassist RTTI & Reflection
JNI用途 • 计算密集任务 • 访问底层硬件 • 访问无java interface的第三方库 JNI
编写JNI模块 • 声明本地方法 • native byte[] loadFile(String name); • 在native环境的映射 /* * Class: ReadFile * Method: loadFile * Signature: (Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile (JNIEnv *, jobject, jstring); JNI
Compile • Gnu C/Linux: • gcc -o libnativelib.so -shared -Wl,-soname,libnative.so -I/export/home/jdk1.2/include -I/export/home/jdk1.2/include/linuxnativelib.c -static -lc • Gnu C++/Linux with Xbase • g++ -o libdbmaplib.so -shared -Wl,-soname,libdbmap.so -I/export/home/jdk1.2/include -I/export/home/jdk1.2/include/linux dbmaplib.cc -static -lc -lxbase • Win32/WinNT/Win2000 • cl -Ic:/jdk1.2/include -Ic:/jdk1.2/include/win32 -LD nativelib.c -Felibnative.dll JNI
Strings • jstring独立于jobject • 从jstring获得对应的UTF Char数组 • C Version: • (*env)->GetStringUTFChars(env, name, iscopy) • C++ Version: • env->GetStringUTFChars(name, iscopy) • 从UTF Char数组构建jstring • (*env)->NewStringUTF(env, lastfile) • 释放资源 • (*env)->ReleaseStringUTFChars(env, name, utfchars); JNI
Arrays • NewTypeArray • GetTypeArrayElements • GetTypeArrayRegion/SetTypeArrayRegion • ReleaseTypeArrayElements • 通过参数控制java对象的改变与native array的释放 • 0:copy back the content and free the elemsbuffer • JNI_COMMIT: copy back the content but do not free the elems buffer • JNI_ABORT:free the buffer without copying back the possible changes JNI
获取Field fid=env->GetFieldID(cls, "arraySize", "I"); if (fid == 0) { cout <<"Can't find field arraySize"; return; } asize=env->GetIntField(jobj,fid); • 调用Java Method • cls=env->GetObjectClass(jobj); • mid=env->GetMethodID(cls, "sendArrayResults", "([Ljava/lang/String;)V"); • env->CallReturnTypeMethod(jobj, mid, ret); • 保存Native指针来保持上下文 JNI
线程同步 env->MonitorEnter(lock); env->CallVoidMethod(jobj, mid, ret); env->MonitorExit(lock); • 内存管理 • JNI LocalReference/GlobalReference • Promote Local to Global jobject* localRef = [...]; jobject* globalRef; globalRef = env->NewGlobalRef(localRef); JNI
Native代码启动虚拟机 • JNI_CreateJavaVM • JNI_DestroyJavaVM • Attaching Thread • (*jvm)->AttachCurrentThread( jvm, (void **)&env, &args); JNI