反射
初始化一个类的子类
Java虚拟机启动时被标明为启动类的类
JDK7 开始提供的动态语言支持:实例的解析结果 。、、句柄对应的类没有初始化 。则初始化
除以上五种情况 。其他使用Java类的方式被看作是对类的被动使用 。都不会导致类的初始化 。
eg:
public class NotInitialization {
public static void main(String[] args) {
//只输出SupperClass int 123,不会输出SubClass init
//对于静态字段 。只有直接定义这个字段的类才会被初始化
System.out.println(SubClass.value);
}
}
class SuperClass {
static {
System.out.println(\"SupperClass init\");
}
public static int value = https://www.wangchuang8.com/123;
}
class SubClass extends SuperClass {
static {
System.out.println(\"SubClass init\");
}
}
类加载器
JVM支持两种类型的类加载器 。分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)
从概念上来讲 。自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器 。但是Java虚拟机规范却没有这么定义 。而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器
启动类加载器(引导类加载器 。Bootstrap ClassLoader)
这个类加载使用C/C++ 语言实现 。嵌套在JVM 内部
它用来加载Java的核心库(、或路径下的内容) 。用于提供JVM自身需要的类
并不继承自。没有父加载器
加载扩展类和应用程序类加载器 。并指定为他们的父类加载器
出于安全考虑 。Boostrap 启动类加载器只加载名为java、Javax、sun等开头的类
扩展类加载器(Extension ClassLoader)
java语言编写 。由实现
派生于 ClassLoader
父类加载器为启动类加载器
从系统属性所指定的目录中加载类库 。或从JDK的安装目录的 子目录(扩展目录)下加载类库 。如果用户创建的JAR 放在此目录下 。也会自动由扩展类加载器加载
应用程序类加载器(也叫系统类加载器 。AppClassLoader)
java语言编写 。由实现
派生于 ClassLoader
父类加载器为扩展类加载器
它负责加载环境变量或系统属性 指定路径下的类库
该类加载是程序中默认的类加载器 。一般来说 。Java应用的类都是由它来完成加载的
通过方法可以获取到该类加载器
public class ClassLoaderTest {
public static void main(String[] args) {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@135fbaa4
//获取其上层:扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@2503dbd3
//再获取其上层:获取不到引导类加载器
ClassLoader bootstrapClassLoader = extClassLoader.getParent();
System.out.println(bootstrapClassLoader);//null
//对于用户自定义类来说 。默认使用系统类加载器进行加载 。输出和systemClassLoader一样
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@135fbaa4
//String 类使用引导类加载器进行加载 。Java的核心类库都使用引导类加载器进行加载 。所以也获取不到
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);//null
//获取BootstrapClassLoader可以加载的api的路径
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (URL url : urls) {
System.out.println(url.toExternalForm());
}
}
}
用户自定义类加载器
在Java的日常应用程序开发中 。类的加载几乎是由3种类加载器相互配合执行的 。在必要时 。我们还可以自定义类加载器 。来定制类的加载方式
为什么要自定义类加载器?
隔离加载类
修改类加载的方式
扩展加载源(可以从数据库、云端等指定来源加载类)
防止源码泄露(Java代码容易被反编译 。如果加密后 。自定义加载器加载类的时候就可以先解密 。再加载)
用户自定义加载器实现步骤
开发人员可以通过继承抽象类类的方式 。实现自己的类加载器 。以满足一些特殊的需求
在JDK1.2之前 。在自定义类加载器时 。总会去继承ClassLoader类并重写loadClass()方法 。从而实现自定义的类加载类 。但是JDK1.2之后已经不建议用户去覆盖loadClass()方式 。而是建议把自定义的类加载逻辑写在findClass()方法中
- Winxp系统电脑虚拟内存不足怎么办?
- 在华为手机中,哪款手机的性价比较高?
- 游戏我的世界是Java版好玩还是PC版好玩?
- 小米手机中口碑最好的是哪款?
- 常用的Java开发软件有哪些?
- C语言入门可以玩单片机,Java、python入门之后可以做啥实际的简单的东西?
- Winxp系统如何添加虚拟网卡?
- 计算机语言入门学哪个好,是JAVA,C++,PYTHON吗?
- 编程初学者应该先学C++、Java还是Python?
- 虚拟内存如何设置?虚拟内存设置多少合适?
