1.JRE是Java运行时环境,包含了运行已编译的Java程序所需的内容,JDK在JRE的基础上还包含了编译器和其它工具。
2.源代码(.java文件)经过JDK中的javac命令编译后,成为字节码(.class)文件,由JVM加载,通过解释器逐行解释执行。
3.new方法每次都会创建一个新的对象,valueOf()方法则会优先判断该值是否位于缓存池,如果在的话就直接返回缓存池中的内容。
4.String不能被继承、具有不可变性、线程安全。
5.String与StringBuffer与StringBuilder
可变性 | 线程安全 | 适用场景 | |
---|---|---|---|
String | 不可变 | 安全 | 操作少量的数据 |
StringBuffer | 可变 | 安全,内部使用synchronized 进行同步 | 多线程操作字符串缓冲区中大量数据 |
StringBuilder | 可变 | 不安全 | 单线程操作字符串缓冲区中大量数据,性能高于StringBuffer |
6.字符串常量池(String Pool)位于方法区,通常保存着所有 字符串字面量 ,在编译期间就被确定。可以用String的 intern()
方法在运行过程中添加到String Pool中。当一个字符串调用intern()
时,如果String Pool中已经存在字面量相同的字符串,则会返回String Pool 中的引用;如果不存在,则向String Pool中添加一个新的字符串,同时返回新字符串的引用;
7.static关键字的四个使用场景:
- 修饰成员变量和成员方法:存储在Java内存中的方法区,被所有对象共享,最好通过
类名.静态成员名/静态方法名()
调用 - 静态代码块:定义在类中的方法外,先于非静态代码块之前执行,不管执行多少次创建新对象的操作,静态代码只执行一次。
- 静态内部类:
static
修饰类时,只有修饰内部类这一种用法。 非静态内部类在编译后会隐含保存一个引用,用于指向创建它的外部类,但是静态内部类不存在。即 静态内部类的创建不用依赖外围类的创建,同时静态内部类也只能使用外部类的static
成员变量和方法 - 静态导包:用于导入静态资源,
import static
用于指定导入某一类中的静态资源,然后我们就可以直接使用类中的静态成员变量和方法。
注:
abstract
方法不能同时是static
的,因为abstract
需要方法需要被重写,但static
方法不可以static
不能用于修饰局部变量- 普通内部类与静态内部类:普通内部类作为外部类的一个成员而存在,可以直接访问外部类属性,调用外部类方法,静态内部类可以直接调用外部类的静态变量和静态方法,但无法直接访问外部类中的普通变量和普通方法,如果要进行访问,必须
new
一个外部类对象,使用该对象来进行访问。
8.final关键字的三个使用场景:
- 修饰类时:被修饰的类不能被继承,而且类中所有成员方法均被隐式指定为
final
方法 - 修饰方法时:该方法无法被重写
- 修饰变量时:该变量是一个常量,若该变量为基本数据类型,则初始化后无法被更改,若该变量为引用类型,则初始化后不能指向其它对象。
9.finally关键字:
- 在异常处理时提供
finally
块来执行任何清除操作,无论是否有异常被抛出或捕获,finally
块均会被执行,通常用于释放资源 finally
正常情况下一定会被执行,但是在如下两种情况下不会执行。
1.对应的try
未执行,则finally
也不会执行
2.若try
块中JVM关机,则finally
也不会执行。finally
中如果有return
语句,则会覆盖try
或catch
中的return
语句,导致两者无法return
,所以建议finally
中不要存在return
关键字.
10.finallize:
finalize()
是Object
类的protected
方法,子类能够覆盖该方法以实现资源清理工作,GC在回收前均会调用该方法,但是该方法存在如下问题:
- Java语言规范不保证
finalize()
方法会被及时执行,也不保证它们一定会被执行 finalize()
方法会带来性能问题,因为JVM通常在单独的低优先线程中完成finalize()
的执行finalize()
方法中,可将待回收对象赋值给GC Root
可达的对象引用,从而达到对象再生的目的finalize()
方法最多由GC执行一次(但是可以手动调用对象的finalize()
方法)
11.this
用于引用当前类的实例,不能用在static
方法中
12.super
用于从子类访问父类中的变量和方法,不能用在static
方法中
13.instanceof
方法用于操作对象实例,检查该对象是否一个特定类型
14.==和equals()
- ==用于基本数据类型时,比较两者的值是否相等,用于引用类型时,比较两者的内存地址是否相等,即两者是否同一对象。
equals()
不可用于基本数据类型,因为它存在于Object()
中,所以所有类都有equals()
方法,当类未覆盖equals()
方法时,等价于使用==比较,当类覆盖了equals()
方法时,则按照覆盖后的逻辑判断。
15.重载:重载就是相同方法根据输入参数的不同做出不同的处理。重载发生在编译期,而且在同一个类中,方法名必须相同,参数类型、参数个数不同,返回值类型可以不同也可以相同,不以返回值类型作为重载区分。
16.重写:当子类继承父类的相同方法,输入数据一样,但最终响应不同于父类;重载发生于运行期;重写方法的方法名、参数列表以及返回值必须相同,抛出的异常范围不超过父类,访问修饰符的范围也不能小于父类。若父类方法由private/final/static
修饰,则子类无法重写父类方法,但static
修饰的方法能再次被声明。构造方法不能被重写。
17.浅拷贝与深拷贝
- 浅拷贝:按位拷贝对象,会创建一个新对象,该对象具有原始对象属性值的精确拷贝。若属性是基本类型,则拷贝的是基本类型的值,若属性是引用类型(内存地址),则拷贝的是内存地址。因此一旦其中任意对象改变了该引用类型,均会影响对方。
- 深拷贝:拷贝所有属性,同时拷贝属性指向动态分配的内存。当对象和它引用的对象一起拷贝时即发生深拷贝,深拷贝比浅拷贝慢且开销更大,但是改变它不会对原来的对象发生影响。
18.面向对象的特点:继承、封装、多态
- 继承:可以使用现有类的所有功能,并且在无须重新编写原来类的情况下对这些功能进行扩展。
- 封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的信息进行隐藏。
- 多态:父对象可以根据当前赋值给它的子对象的特性以不同的方式运作。
19.接口
- 接口中所有方法默认是
public
,Java 8 之前不能有实现,Java 8 之后可以由默认实现 - 接口中所有变量均为
static final
- 一个类可以实现多个接口,且接口可以继承接口
- 接口是对行为的抽象、属于行为规范
20.抽象类
- 抽象类中既可以有抽象方法,也可以有非抽象方法
- 一个类只能实现一个抽象类
- 抽象方法不能被
private
修饰 - 抽象是对类的抽象,是一种模板设计
21.equals()
方法重写例子
判断逻辑按照需求写,这里仅供参考。
@Override
public boolean equals(Object obj) {
//是否同一对象
if(this == obj)
return true;
//是否为空
if(obj == null)
return false;
//是否当前类对象
if(obj instanceof Father) {
Father father =(Father) obj;
//判断逻辑
if(father.age==this.age) {
return true;
}
}
return false;
}
参考链接
1.Java 面试高频知识点总结基础篇(2020)
2.java8之默认接口实现
3.如何通俗易懂地举例说明「面向对象」和「面向过程」有什么区别?
4.java提高篇(三)-----理解java的三大特性之多态