Java 面试题整理(三)

目录

反射机制以及反射的方式

类加载有几种方式

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)栈的数据大小与生存期必须是确定的,缺乏灵活性。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值