2023.2.14(第二天)
数组是不是对象?
在Java中,数组是对象。数组是一种引用类型,它可以存储固定大小的相同类型的元素序列。在Java中,数组是通过new
关键字创建的,它们在内存中被分配为对象,而数组的元素则被存储在数组对象的连续内存位置上。
数组在Java中具有对象的特征和行为,包括以下方面:
- 数组可以存储任意类型的元素,包括基本数据类型和对象引用。
- 数组可以通过索引访问和修改元素。
- 数组具有length属性,用于获取数组的长度。
- 数组可以作为参数传递给方法,也可以作为方法的返回值。
- 数组可以通过
clone()
方法进行复制,也可以通过toString()
方法将其转换为字符串。
因此,在Java中,数组被视为对象,它们具有对象的特征和行为,并且在内存中被分配为对象。
Java的八种基本数据类型有哪些?
- byte,8bit
- char,16bit
- short,16bit
- int,32bit
- float,32bit
- long,64bit
- double,64bit
- boolean,只有两个值:true、false,可以使⽤用 1 bit 来存储
BigDecimal
是 Java 中的一个类,用于表示任意精度的十进制数。它可以用于处理需要高精度计算的场景,例如金融领域或需要保留小数位数的计算。
BigDecimal
类的特点包括:
- 任意精度: 可以表示任意长度的十进制数,不会出现精度丢失的问题。
- 精确计算: 提供了精确的算术运算,包括加法、减法、乘法、除法和取余。
- 不可变性:
BigDecimal
对象是不可变的,一旦创建,其值就不会改变。 - 舍入模式: 可以指定舍入模式来控制结果的舍入行为。
使用 BigDecimal
类可以避免由于浮点数表示误差而导致的计算不准确的问题。在需要对数值进行高精度计算或要求结果精确的情况下,通常会使用 BigDecimal
类。
Java 中使用 BigDecimal 来处理高精度数字。您可以创建 BigDecimal 对象并执行高精度的加法、减法、乘法和除法运算。
什么是值传递和引用传递?
- 值传递传递的是值的副本,对参数的修改不会影响原始值;
- 引用传递传递的是值的引用,对参数的修改会影响原始值。在不同的编程语言中,参数传递的方式可能有所不同。
java中是值传递还是引用传递?
在Java中,参数传递的方式统一为值传递(Pass by Value)。这意味着在方法调用时,传递给方法的是实际参数的副本,而不是参数本身。
自动装箱和拆箱
在Java中,基本数据类型和它们对应的包装类之间存在自动装箱(Autoboxing)和自动拆箱(Unboxing)的功能。
定义:
- 自动装箱是指将基本数据类型自动转换为对应的包装类对象,
- 自动拆箱是指将包装类对象自动转换为对应的基本数据类型。
以下是Java中基本数据类型与它们对应的包装类的对应关系:
基本数据类型 | 包装类 |
---|---|
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
// 自动装箱
Integer num = 10; // 将int类型的值自动装箱为Integer对象// 自动拆箱
int value = num; // 将Integer对象自动拆箱为int类型的值
demo
public class AutoBoxingUnboxingDemo {public static void main(String[] args) {// 自动装箱:将int类型转换为Integer对象Integer num1 = 10;// 自动拆箱:将Integer对象转换为int类型int num2 = num1;System.out.println("自动装箱后的值: " + num1); // 输出 10System.out.println("自动拆箱后的值: " + num2); // 输出 10// 自动装箱和拆箱也适用于其他基本数据类型和对应的包装类Double doubleValue = 3.14;double doublePrimitive = doubleValue;System.out.println("自动装箱后的double值: " + doubleValue); // 输出 3.14System.out.println("自动拆箱后的double值: " + doublePrimitive); // 输出 3.14}
}
运行结果
2023.2.13(第一天)
Java是如何实现跨平台的?
Java是通过JVM(Java虚拟机)实现跨平台的。
JVM可以理解成一个软件,不同的平台有不同的版本。我们编写的Java代码,编译后会生成.class 文件(字节码文件)。Java虚拟机就是负责将字节码文件翻译成特定平台下的机器码,通过JVM翻译成机器码之后才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。
只要在不同平台上安装对应的JVM,就可以运行字节码文件,运行我们编写的Java程序。
因此,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的翻译才能执行。
面向对象和面向过程的区别?
面向对象和面向过程是一种软件开发思想。
-
面向过程就是分析出解决问题所需要的步骤,然后用函数按这些步骤实现,使用的时候依次调用就可以了。
-
面向对象是把构成问题事务分解成各个对象,分别设计这些对象,然后将他们组装成有完整功能的系统。面向过程只用函数实现,面向对象是用类实现各个功能模块。
Java 与 C++ 的区别
- Java 是纯粹的面向对象语言,所有的对象都继承自 java.lang.Object,C++ 兼容 C ,不但支持面向对象也支持面向过程。
- Java 通过虚拟机从而实现跨平台特性, C++ 依赖于特定的平台。
- Java 没有指针,它的引用可以理解为安全指针,而 C++ 具有和 C 一样的指针。
- Java 支持自动垃圾回收,而 C++ 需要手动回收。
- Java 不支持多重继承,只能通过实现多个接口来达到相同目的,而 C++ 支持多重继承。
JDK/JRE/JVM三者的关系
JVM
英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。Java 能够跨平台运行的核心在于 JVM 。
所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。也就是说class文件并不直接与机器的操作系统交互,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
针对不同的系统有不同的 jvm 实现,有 Linux 版本的 jvm 实现,也有Windows 版本的 jvm 实现,但是同一段代码在编译后的字节码是一样的。这就是Java能够跨平台,实现一次编写,多处运行的原因所在。
JRE
英文名称(Java Runtime Environment),就是Java 运行时环境。我们编写的Java程序必须要在JRE才能运行。它主要包含两个部分,JVM 和 Java 核心类库。
JRE是Java的运行环境,并不是一个开发环境,所以没有包含任何开发工具,如编译器和调试器等。
如果你只是想运行Java程序,而不是开发Java程序的话,那么你只需要安装JRE即可。
JDK
英文名称(Java Development Kit),就是 Java 开发工具包。JDK目录下有个JRE,也就是JDK中已经集成了 JRE,不用单独安装JRE。
他们三者的关系
JRE = JVM + Java 核心类库
JDK = JRE + Java工具 + 编译器 + 调试器
面向对象有哪些特性?
面向对象三大特性:封装,继承,多态,
1、封装就是将类的信息隐藏在类内部,不允许外部程序直接访问,而是通过该类的方法实现对隐藏信息的操作和访问。 良好的封装能够减少耦合。
2、继承是从已有的类中派生出新的类,新的类继承父类的属性和行为,并能扩展新的能力,大大增加程序的重用性和易维护性。在Java中是单继承的,也就是说一个子类只有一个父类。
3、多态是同一个行为具有多个不同表现形式的能力。在不修改程序代码的情况下改变程序运行时绑定的代码。实现多态的三要素:继承、重写、父类引用指向子类对象。
- 静态多态性:通过重载实现,相同的方法有不同的參数列表,可以根据参数的不同,做出不同的处理。
- 动态多态性:在子类中重写父类的方法。运行期间判断所引用对象的实际类型,根据其实际类型调用相应的方法。
面向对象编程的六大原则?
- 对象单一职责:我们设计创建的对象,必须职责明确,比如商品类,里面相关的属性和方法都必须跟商品相关,不能出现订单等不相关的内容。这里的类可以是模块、类库、程序集,而不单单指类。
- 里式替换原则:子类能够完全替代父类,反之则不行。通常用于实现接口时运用。因为子类能够完全替代基(父)类,那么这样父类就拥有很多子类,在后续的程序扩展中就很容易进行扩展,程序完全不需要进行修改即可进行扩展。比如IA的实现为A,因为项目需求变更,现在需要新的实现,直接在容器注入处更换接口即可.
- 迪米特法则,也叫最小原则,或者说最小耦合。通常在设计程序或开发程序的时候,尽量要高内聚,低耦合。当两个类进行交互的时候,会产生依赖。而迪米特法则就是建议这种依赖越少越好。就像构造函数注入父类对象时一样,当需要依赖某个对象时,并不在意其内部是怎么实现的,而是在容器中注入相应的实现,既符合里式替换原则,又起到了解耦的作用。
- 开闭原则:开放扩展,封闭修改。当项目需求发生变更时,要尽可能的不去对原有的代码进行修改,而在原有的基础上进行扩展。
- 依赖倒置原则:高层模块不应该直接依赖于底层模块的具体实现,而应该依赖于底层的抽象。接口和抽象类不应该依赖于实现类,而实现类依赖接口或抽象类。
- 接口隔离原则:一个对象和另外一个对象交互的过程中,依赖的内容最小。也就是说在接口设计的时候,在遵循对象单一职责的情况下,尽量减少接口的内容。
什么是值传递和引用传递?
- 值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。
- 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身,两者指向同一片内存空间。所以对引用对象进行操作会同时改变原对象。
java中不存在引用传递,只有值传递。即不存在变量a指向变量b,变量b指向对象的这种情况。
自动装箱和拆箱
Java中基础数据类型与它们对应的包装类见下表:
原始类型 | 包装类型 |
---|---|
boolean | Boolean |
byte | Byte |
char | Character |
float | Float |
int | Integer |
long | Long |
short | Short |
double | Double |
装箱:将基础类型转化为包装类型。
拆箱:将包装类型转化为基础类型。
当基础类型与它们的包装类有如下几种情况时,编译器会自动帮我们进行装箱或拆箱:
- 赋值操作(装箱或拆箱)
- 进行加减乘除混合运算 (拆箱)
- 进行>,<,==比较运算(拆箱)
- 调用equals进行比较(装箱)
- ArrayList、HashMap等集合类添加基础类型数据时(装箱)
String, StringBuffer 和 StringBuilder区别
1. 可变性
- String 不可变
- StringBuffer 和 StringBuilder 可变
2. 线程安全
- String 不可变,因此是线程安全的
- StringBuilder 不是线程安全的
- StringBuffer 是线程安全的,内部使用 synchronized 进行同步