Java面试宝典总结(一)

1.ClassLoader类

1.1类加载器的一些基础概念

ClassLoader在JVM运行的时候回加载Java核心的API,以满足程序最基本的需求。Java主要有三个类加载器:Bootstrap Loader、ExtClassLoader和AppClassLoader。

Bootstrap Loader是由C++编写的。称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中相关的类库,例如rt.jar、resource.jar等。默认加载的是jre/lib或者jre/classes下的jar文件。

ExtClassLoader称为扩展类加载器,负责加载java的扩展类库,默认加载的是jre/lib/ext目录下的所有jar。

AppClassLoader称为系统类加载器,默认加载的是classpath目录下的所有jar和class文件。

注意: 除了Java默认提供的三个ClassLoader之外,用户还可以根据需要定义自已的ClassLoader,而这些自定义的ClassLoader都必须继承自java.lang.ClassLoader类,也包括Java提供的另外二个ClassLoader(Extension ClassLoader和App ClassLoader)在内

1.2类加载流程

当运行一个程序的时候,JVM启动,运行Bootstrap classLoder,该ClassLoader加载Java核心API。之后会载入ExtClassLoader,并且将ExtClassLoder的parent设为BootstrapLoader。ExtClassLoader会加载扩展API。然后BootstrapLoader再载入AppClassLoader,并且将AppClassLoader的parent设为ExtClassLoader。AppClassLoader会加载classpath目录下的class和jar。自底向上检查类是否加载,自顶向下加载类。

注意:JVM在判断两个类是否相同时,不仅要判断类名是否相同,还要判断两个类是否是同一个类加载器实例ss加载的。

JVM加载类的时候需要三步:装载、连接、初始化。装载就是找到相应的类,读入JVM;连接分为三步:第一步验证class是否符合规格,第二步准备,为类变量分配内存的同时设置初始默认值,第三步解释,是指根据类中的符号引用查找相应的实体,再把符号引用替换成一个直接引用的过程。初始化即class文件初始化。Class类中的Class.forName()方法在加载的时候回将Class进行解释和初始化。而ClassLoader不会,它仅仅加载了类。

2.Java使用了中间缓存变量的机制

j = j++;这句有两个操作:赋值和自增。其中赋值又可以分解为两个操作:读出一个值(到缓存),将该值赋给变量。所以我们有三个操作要完成:
  1. 读取变量j的值到缓存;
  2. 改变变量j的值为缓存值;
  3. 改变变量j的值,将其增1。
关键在于这三者的顺序。在java中,上述语句实际操作顺序为:1 - 3 - 2。所以:
  • 读取变量j的值 (0) 到缓存。
  • 改变变量j的值,将其增1 (变为1)。
  • 改变变量j的值为缓存值 (变为0)。

在Java中执行自增自减运算时,会为每一个操作分配一个临时变量,如果是++i,先i=i+1,再将i的值赋给临时变量;如果是i++,先赋给临时变量,再加1。运算最终使用的值是临时变量,而不是变量本身。

例如:

i = i++ + ++i;(i的初值为0)      ----答案为 2

i++等于如下两步:
int temp = i = 0;
i = i + 1 = 1;

++i等于如下两步:
i = i + 1 = 2;
int temp = i;

最后两个temp相加等于2赋给i;
3.三目运算中第一个是返回布尔值的表达式,后面两个操作数或者表达式必须返回类型一致。

两边的操作数不一致时,涉及到三元操作符的转换规则:

若两个操作数不可转换,返回值为Object类型;

若两个操作数有明确类型的表达式(比如变量),则按照正常的二进制数字来转换,int转换为long类型,long转换为float类型;

若两个操作数中有一个是数字S,另一个是表达式,且类型为T,若数字S在T的范围内,则转换为T类型;若S超过了T的范围,则T转换为S类型。

若两个操作数都是直接数字,则返回值类型为范围较大者。

4.& 、|、^ 这三个除了是位运算符之外,还可以充当布尔逻辑运算符,前提是两边的数据类型都要是布尔类型。布尔逻辑运算符的优先级要高于逻辑运算符。最大的区别是 布尔逻辑运算符是非短路运算,逻辑运算符是短路运算。

短路运算:但凡&&前面的是false,则后面的表达式不再做了。但凡||前面的是true,后面的表达式也不用继续运算。

非短路运算:无论运算符前面的是true或者false,运算符后面的表达式都要继续运算。

5.Java中若移位运算,会对移位的位数先进行模32或者模64运算,再移位。

6.final关键字

6.1final成员:这个变量一旦被初始化,便不可改变。意思是对基本类型来说其值是不可变的,而对于对象变量来说其引用不可变。初始化可以在两个地方,一个是其定义处,一个是构造函数中。

6.2final方法:将方法声明为final有两个原因,一个是已经知道该方法提供的功能满足要求,不需要进行扩展,并且不允许任何从此类继承的类来覆写这个方法,但是可以继承,可以使用。第二就是允许编译器将所有对此方法的调用转化为inline调用的机制。在调用final方法时,直接将代码主题插入到调用处。

6.3final类:无法被任何类继承,且所有的方法就是final类型。类中的成员可以是final型,也可以不是final型。

7.finalize:该方法是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

8.反射机制:反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。通过反射机制访问java对象的属性,方法和构造方法等。

8.1通过反射得到类对象

//第一种方法
Class c1 = Class.forName("Employee");

//第二种方法
Class c2 = Employee.class;

//第三种方法
Employee e = new Employee();
Class c3 = e.getClass();
8.2获取到类以后创建对象

Object o = c1.newInstance();



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值