代码随想录知识星球精华(最强⼋股⽂)第五版
(Java篇))
代码随想录知识星球精华(最强⼋股⽂)第五版为九份PDF,分别是:
代码随想录知识星球⼋股⽂概述
C++篇
go篇
Java篇
前端篇
算法题篇
计算机基础篇
问答精华篇
⾯经篇
本篇为最强⼋股⽂之Java篇。
⾯试题
绝⼤部分内类来⾃ 代码随想录知识星球 ,部分参考有 JavaGuide、 ⽜客⽹,还有⼀些博客资料,标注如有疏
漏,敬请谅解。
JavaSE
Java概述
1、JVM、JRE、JDK之间的关系
JVM负责将Java字节码翻译成机器码,以便在特定平台上执⾏Java程序。
JDK是Java的开发⼯具包,它包含了开发和编译Java程序所需的⼯具,以及运⾏Java程序的JRE
JRE是Java应⽤程序运⾏的环境,它包含了运⾏Java程序所需的库、Java虚拟机(JVM)以及其他⽀持⽂件。
简⽽⾔之,JVM提供了Java程序运⾏的虚拟环境,JDK是⽤于开发Java程序的⼯具包,⽽JRE是⽤于运⾏Java程序的
环境。在开发阶段,你需要JDK;⽽在部署和运⾏阶段,你只需要JRE。
Java基础数据类型
Java有⼏种数据类型
整型: byte 、short、int、long (int默认)
浮点型: float 、double (double默认)
布尔型: boolean
字符型: char
对应的包装类为 Byte 、 Short 、 Integer 、 Long 、 Float 、 Double 、 Character 、 Boolean
基础数据类型的转换⽅式
⾃动类型转换:⼩–>⼤ byte --> short --> int --> long --> float --> double
强制类型转换:⼤–>⼩ ⼩类型 变量名 = (⼤类型) 值
注意:⾃增/⾃减运算符、复合赋值运算符底层做了优化,内部⾃动强制类型转换; 如:++, --, +=, -=, ......
基本类型和包装类型的区别
为了在对象环境中使⽤基本类型,Java提供了对应的包装类型。
基本类型直接存储数据值,在栈上分配内存,占⽤固定的内存空间,
包装类型是对象动态分配内存,在堆上创建,包含额外的信息,例如⽅法和字段,同时也占⽤更多的内存空
间。
不过Java提供了⾃动装箱(autoboxing)和拆箱(unboxing)的功能,使得基本类型和包装类型之间的转换更加
⽅便。
什么是⾃动装箱和⾃动拆箱
⾃动装箱是指将基本类型转换为对应的包装类型,⽽⾃动拆箱是指将包装类型转换为对应的基本类型。这些转换通
常由编译器⾃动处理。
装箱其实就是调⽤了 包装类的 valueOf() ⽅法,拆箱其实就是调⽤了 xxxValue() ⽅法。
注意:所有整型包装类对象之间值的⽐较,全部使⽤ equals ⽅法⽐较。
变量和⽅法
成员变量和局部变量的区别
1. 声明位置:
成员变量: 声明在类中,但在⽅法、构造函数或块之外。它们是类的⼀部分,因此可以被整个类的⽅法访
问。
局部变量: 声明在⽅法、构造函数或块中。它们只在声明它们的⽅法、构造函数或块中可⻅。
2. 作⽤域
成员变量: 具有类的整个实例的⽣命周期,可以在整个类中使⽤。
局部变量: 仅在声明它们的⽅法、构造函数或块中可⻅,并且只在该⽅法、构造函数或块的执⾏期间存在。
3. ⽣命周期
成员变量: 随着对象的创建⽽创建,随着对象的销毁⽽销毁。
局部变量: 在声明时分配内存,在⽅法调⽤结束时销毁。
4. 默认值
成员变量: 如果不显式初始化,会有默认值(例如,整数默认为0,对象引⽤默认为null等)。
局部变量: 不会⾃动初始化,必须在使⽤之前显式初始化。
// ⾃动装箱
Integer intValue = 42; // 将基本类型int⾃动转换为Integer包装类型
// ⾃动拆箱
int primitiveValue = intValue; // 将Integer包装类型⾃动转换为基本类型int
public class Example {
// 成员变量
private int memberVariable;
public void exampleMethod() {
// 局部变量
int localVar = 10;
// ...
}
}
静态变量是什么?
静态变量是被 static 关键字修饰的变量,被类的所有实例共享,⽆论⼀个类创建了多少个对象,它们都共享同⼀
份静态变量。静态变量通过类名来访问。
值传递和引⽤传递的区别
参数传递⽅式主要有值传递和引⽤传递两种,但需要注意的是 Java 中的参数传递是始终按值传递的。
值传递:在值传递中,传递给函数的是实际参数的值的副本。当在函数内修改这个副本时,不会影响到原始值
引⽤传递:⽅法接收的直接是实参所引⽤的对象在堆中的地址,不会创建副本,对形参的修改将影响到实参。
但在 Java 中,虽然传递的是引⽤的值(对象的地址),但仍然是按值传递。实际上,传递的是引⽤的副本,因此
在函数内对引⽤的修改会影响到原始的引⽤,但⽆法修改引⽤指向的对象。
类和对象
⾯向对象和⾯向过程有什么区别
⾯向对象编程(OOP)和⾯向过程编程是两种不同的编程范式。
⾯向对象会先抽象出具有状态、⾏为的对象,然后⽤对象执⾏⽅法的⽅式解决问题,强调封装、继承和多态,
更容易扩展和维护,因为修改⼀个对象不会影响到其他对象,适合处理复杂的系统。
⾯向过程将系统视为⼀系列的过程或函数,通过调⽤这些过程来完成任务。强调的是算法和流程, 如果需要
修改⼀个过程,可能会影响到调⽤这个过程的其他地⽅,更适合简单的、线性的任务。
⾯向对象的三⼤特征
1. 封装
为了提⾼代码的安全性,隐藏对象的内部细节,封装将对象的内部状态(字段、属性)隐藏起来,并通过定义公共
的⽅法(接⼝)来操作对象,外部代码只需要知道如何使⽤这些⽅法⽽⽆需了解内部实现。
2. 继承
允许⼀个类(⼦类)继承另⼀个类(⽗类)的属性和⽅法的机制。⼦类可以重⽤⽗类的代码,并且可以通过添加新
的⽅法或修改(重写)已有的⽅法来扩展或改进功能,提⾼了代码的可重⽤性和可扩展性。
3. 多态
多态是指相同的操作或⽅法可以在不同的对象上产⽣不同的⾏为,通过⽅法的重载和重写实现。多态允许以⼀致的
⽅式处理不同类型的对象,提⾼了代码的灵活性。
说⼀说你对多态的理解
因为⼦类其实是⼀种特殊的⽗类,因此Java允许把⼀个⼦类对象直接赋给⼀个⽗类引⽤变量,⽆须任何类型转换,
或者被称为向上转型,向上转型由系统⾃动完成。
当把⼀个⼦类对象直接赋给⽗类引⽤变量时,例如 BaseClass obj = new SubClass(); ,这个 obj 引⽤变量的
编译时类型是 BaseClass ,⽽运⾏时类型是 SubClass ,当运⾏时调⽤该引⽤变量的⽅法时,其⽅法⾏为总是表
现出⼦类⽅法的⾏为特征,⽽不是⽗类⽅法的⾏为特征,这就可能出现:相同类型的变量、调⽤同⼀个⽅法时呈现
出多种不同的⾏为特征,这就是多态。
编译时多态和运⾏时多态的区别
1. 编译时多态
编译时多态也被称为静态多态或早期绑定。它是指在编译阶段,编译器就能够确定调⽤哪个⽅法,这是通过⽅法的
重载来实现的。编译时多态主要依赖于⽅法的签名(⽅法名和参数列表),根据调⽤时提供的参数类型和数量来确
定具体调⽤的⽅法。
2. 运⾏时多态
运⾏时多态也被称为动态多态或晚期绑定。指的是在程序运⾏时,根据实际对象的类型来确定调⽤的⽅法,这是通
过⽅法的重写来实现的。运⾏时多态主要依赖于对象的实际类型,⽽不是引⽤类型。
3. 总结
public class Example {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public static void main(String[] args) {
Example example = new Example();
int resultInt = example.add(2, 3); // 编译时确定调⽤add(int, int)
double resultDouble = example.add(2.0, 3.0); // 编译时确定调⽤add(double, double)
}
}
class Animal {
void makeSound() {
System.out.println("sound");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Bark");
}
}
public class PolymorphismExample {
public static void main(String[] args) {
Animal myDog = new Dog(); // 运⾏时多态,myDog的实际类型是Dog
myDog.makeSound(); // 运⾏时确定调⽤Dog类的makeSound⽅法
}
}