目录
Class.forName()和ClassLoader.loadClass()的区别
如何防止创建的类名不能为Java为已有类,Java加载双亲委派机制
反射机制以及反射的方式
参考至:Java反射机制的基本概念与使用_小草的博客-CSDN博客_java中反射的概念
1. Java反射机制是什么
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2. 反射机制提供的功能
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
3. 反射的方式(三种)
1)通过Object类的getClass(),获得该类的字节码文件(.class文件)
List<String> list = new ArrayList<>();
Class<?> clazz_3 = list.getClass();
2)通过”类.class”方式
需要输入一个明确的类,任意一个类型都有一个静态的class属性
Class<?> clazz_2 = ArrayList.class;
3)通过Class.forName()方式
通过Class类的一个forName(String className)静态方法返回一个Class对象,className必须是全路径名称
Class<?> clazz_1 = Class.forName("java.util.ArrayList");
类加载有几种方式
共三种方式
1. 由new关键字创建一个类的实例
List<String> list_1 = new ArrayList<>();
2. 使用Class.forName()方法
通过反射加载类型
Class<?> clazz_2 = Class.forName("java.util.ArrayList");
List<String> list_2 = (List<String>) clazz_2.newInstance();
3. 调用某个ClassLoader实例的loadClass()方法
通过该ClassLoader实例的loadClass()方法载入。应用程序可以通过继承ClassLoader实现自己的类加载器。
1)加载其他类,必须要有一个ClassLoader实例对象
ClassLoader classLoader = new ClassLoader() {};
Class<?> clazz_3 = classLoader.loadClass("java.util.ArrayList");
List<String> list_3 = (List<String>) clazz_3.newInstance();
2)加载当前类,直接使用当前类的类加载器
Class<?> clazz = Demo_1.class.getClassLoader().loadClass("reflect.Demo_1");
Demo_1 demo_1 = (Demo_1) clazz.newInstance();
Class.forName()和ClassLoader.loadClass()的区别
参考至:反射中Class.forName()和ClassLoader.loadClass()的区别 - Jerry迎风 - 博客园
1. 类装载过程
加载
通过类的全限定名获取二进制字节流,将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象;
链接
执行下面的验证、准备和解析步骤,其中解析步骤是可以选择的;
校验:检查导入类或接口的二进制数据的正确性;(文件格式验证,元数据验证,字节码验证,符号引用验证)
准备:给类的静态变量分配并初始化存储空间;
解析:将常量池中的符号引用转成直接引用;
初始化
激活类的静态变量的初始化Java代码和静态Java代码块,并初始化程序员设置的变量值
2. 区别
Class.forName(),会执行static静态代码块以及初始化static参数;
ClassLoader.loadClass(),不会执行静态块和静态对象。
3. 数据库链接为什么使用Class.forName(className)
Class.forName(classname)才能在反射回去类的时候执行static块
JDBC Driver源码如下:
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
如何防止创建的类名不能为Java为已有类,Java加载双亲委派机制
某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
rt.jar类库: JAVA基础类库,基础数据类型等io.lang. 比如里面有String类Long类等。
堆和栈的区别
推荐: 牛客 - Java专项练习题知识点整理(三)中的前三个知识点
堆--用new建立,垃圾自动回收负责回收;在JDK8,字符串常量从方法区移到到堆中
1) 堆是一个"运行时"数据区,类实例化的对象就是从堆上去分配空间的;
2)在堆上分配空间是通过"new"等指令建立的;
3)Java针对堆的操作和C++的区别就是,Java不需要在空间不用的时候来显式的释放;
4)Java的堆是由Java的垃圾回收机制来负责处理的,堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。
5)但缺点是,因为在运行时动态分配内存,所以内存的存取速度较慢。
栈
1)虚拟机栈和本地方法栈
2)栈中主要存放一些基本类型的变量和对象句柄;
3)栈的存取速度比堆要快;
4)栈数据可以共享;
5)栈的数据大小与生存期必须是确定的,缺乏灵活性。