有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准https://blog.zysicyj.top
1. 什么是 String?在 Java 中,String 是一个类,用于表示字符串。它是不可变的,即一旦创建就不能被修改。
2. 为什么 String 是不可变的?String 被设计成不可变的主要有以下几个原因:
2.1 字符串常量池 在 Java 中,存在一个字符串常量池(StringPool),它是存储字符串对象的特殊内存区域。当我们创建一个字符串时,如果该字符串已经存在于字符串常量池中,那么就会直接返回这个字符串的引用;如果不存在,则会将该字符串添加到字符串常量池中,并返回新创建的字符串的引用。
由于字符串常量池的存在,多个字符串可以共享同一个实例,这样可以节省内存空间。而如果 String 是可变的,那么在修改字符串时,可能会导致其他使用相同字符串的地方出现问题。
2.2 安全性 由于 String 是不可变的,所以它在多线程环境下是安全的。多个线程可以同时访问和共享同一个字符串对象,而无需担心数据的修改问题。
2.3 缓存哈希值 Stri ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
1. 什么是 String、StringBuffer 和 StringBuilder?
String 是 Java 中的一个类,用于表示字符串。它是不可变的,即一旦创建就不能被修改。
StringBuffer 和 StringBuilder 也是 Java 中的类,用于表示可变的字符串。它们可以进行插入、删除和替换等操作。
2. 为什么需要 String、StringBuffer 和 StringBuilder? 在实际开发中,我们经常需要对字符串进行拼接、修改和处理。而由于 String 是不可变的,每次对 String 进行修改都会生成一个新的 String 对象,这样会导致频繁的内存分配和回收,影响性能。为了解决这个问题,Java 提供了 StringBuffer 和 StringBuilder 两个可变的字符串类,它们可以高效地进行字符串的操作。
3. String、StringBuffer 和 StringBuilder 的实现原理?
St ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
equals() 方法用于比较两个对象是否相等,而 hashCode() 方法用于获取对象的哈希码。
在 Java 中,如果两个对象通过 equals() 方法判断为相等,则它们的 hashCode() 方法必须返回相同的值。这是因为在使用哈希表(如 HashMap、HashSet)等数据结构时,会先根据对象的哈希码确定存储位置,然后再使用 equals() 方法进行比较来确保唯一性。
如果重写了 equals() 方法但没有重写 hashCode() 方法,那么可能会导致以下问题:
当将对象放入哈希表中时,由于 hashCode() 返回的不是相同的值,哈希表无法正确定位到该对象所在的位置,从而无法正常操作该对象。
当使用哈希集合(如 HashSet)时,由于 hashCode() 返回的不是相同的值,哈希集合无法正确判断两个对象是否相等,从而可能导致重复元素的存在。
因此,在重写 equals() 方法时,必须同时重写 hashCo ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准https://blog.zysicyj.top
1. 什么是 hashCode()?hashCode() 是 Java 中的一个方法,它用于返回对象的哈希码。哈希码是根据对象的内容计算出来的一个整数值。
2. 为什么需要 hashCode()?在 Java 中,我们经常需要对对象进行比较和存储。使用 hashCode() 方法可以提高对象比较和存储的效率。
对象比较:当我们需要判断两个对象是否相等时,通常会先比较它们的哈希码,如果哈希码不同,则可以直接判定两个对象不相等,从而避免了比较所有属性的开销。
对象存储:在集合类(如 HashMap、HashSet)中,对象的哈希码被用作索引或者散列桶的位置,通过哈希码可以快速定位到对象所在的位置,从而提高查找和插入的效率。
3. hashCode() 的实现原理?在 Java 中,默认情况下,hashCode() 方法是根据对象的内存地址计算得到的。也就是说,每个对象都有一个唯一的哈希码。
然而,在实际应用中,我们往往需要根据对象的内容来计算哈希码,以便能 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准https://blog.zysicyj.top
1. 什么是 == 和 equals()?== 是 Java 中的一个操作符,用于比较两个变量的值是否相等。对于基本数据类型(如 int、float 等),==比较的是它们的值;对于引用类型(如对象),== 比较的是它们在内存中的地址。
equals() 是 Object 类中定义的方法,用于比较两个对象是否相等。默认情况下,equals() 方法与 ==的作用是一样的,即比较两个对象的内存地址。但是,可以通过重写 equals() 方法来改变其行为,使其比较对象的内容而不是地址。
2. 为什么需要 == 和 equals()?在编程过程中,我们经常需要比较两个变量或对象是否相等。使用 == 可以快速判断两个基本数据类型的值是否相等,而使用 equals()可以更灵活地比较两个对象的内容。
3. == 和 equals()的实现原理?
对于基本数据类型,== 操作符直接比较它们的值。
对于引用类型 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
Object 类是所有类的根类,在 Java 中,它定义了一些常见的方法。下面是 Object 类的常见方法:
**equals(Object obj)**:用于比较两个对象是否相等。默认情况下,使用 == 运算符进行比较,即判断两个对象的引用是否指向同一个内存地址。如果需要自定义比较规则,可以重写该方法。
**hashCode()**:返回对象的哈希码值。哈希码是根据对象的内容计算得出的一个整数,用于快速查找和比较对象。在重写 equals 方法时,通常也要同时重写 hashCode 方法,以保证相等的对象具有相同的哈希码。
**toString()**:将对象转换为字符串表示形式。默认情况下,返回对象的类名和哈希码。可以通过重写该方法来返回更有意义的字符串。
**getClass()**:返回对象的运行时类。返回的是 Class 对象,可以获取类的信息,如类名、父类、接口等。
**clone()**:创建并返回当前对象 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
深拷贝和浅拷贝的区别:
深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在进行对象拷贝时常用的两种方式,它们之间的主要区别在于是否复制了对象内部的数据。
浅拷贝只是简单地将原对象的引用赋值给新对象,新旧对象共享同一块内存空间。当其中一个对象修改了这块内存中的数据时,另一个对象也会受到影响。
深拷贝则是创建一个全新的对象,并且递归地复制原对象及其所有子对象的内容。新对象与原对象完全独立,对任何一方的修改都不会影响另一方。
引用拷贝:
引用拷贝是指将一个对象的引用直接赋值给另一个变量,使得两个变量指向同一个对象。这样,在修改其中一个变量所指向的对象时,另一个变量也会随之改变。
引用拷贝通常发生在传递参数、返回值等场景中。例如,在 Java 中,如果将一个对象作为参数传递给方法,实际上是将该对象的引用传递给了方法,而不是对象本身的拷贝。
需要注意的是,引用拷贝并非真正意义上的拷贝,而是共享同一份数据。因此,对于引用拷贝的 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准https://blog.zysicyj.top
1. 什么是接口和抽象类?接口 是一种定义了一组方法签名的集合,这些方法可以被实现该接口的任何类所实现。接口中的方法默认都是公共的抽象方法,不包含具体的实现代码。
抽象类 是一个不能被实例化的类,它只能作为其他类的父类来使用。抽象类可以包含抽象方法和非抽象方法,其中抽象方法没有具体的实现,而非抽象方法有具体的实现代码。
2. 接口和抽象类的共同点
都是用于实现多态性的机制。
都不能被实例化,只能被子类继承或实现。
都可以包含抽象方法,需要由子类提供具体的实现。
3. 接口和抽象类的区别
语法上的区别 :接口使用interface 关键字进行声明,抽象类使用 abstract 关键字进行声明。
实现方式的区别:一个类可以实现多个接口,但只能继承一个抽象类。
成员变量的区别:接口中只能定义常量(即静态 final 字段),而抽象类可以定义普通成员变量。
构造函数的区别:接口没有构造函数,而抽象类可以有构造函数。
方法实现的区别:接口中的方法默认都是公共的 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
面向对象编程的三大特征是封装、继承和多态。
封装 :封装是指将数据和操作数据的方法(即函数)捆绑在一起,形成一个类。通过封装,我们可以隐藏内部实现细节,只暴露必要的接口给外部使用。这样可以提高代码的可维护性和安全性,并且方便其他开发者使用该类。
继承 :继承是指一个类可以派生出子类,子类会继承父类的属性和方法。通过继承,子类可以重用父类的代码,并且可以在不修改父类的情况下进行功能扩展。继承可以建立类之间的层次关系,使得代码更加灵活和可扩展。
多态 :多态是指同一个方法名可以根据调用对象的不同而表现出不同的行为。具体来说,当一个父类引用指向一个子类对象时,通过调用相同的方法名,可以触发子类中对应的方法。多态可以增加代码的灵活性和可复用性,同时也符合面向对象的设计原则。
总结:
封装可以隐藏内部实现细节,提高代码的可维护性和安全性。
继承可以重用父类的代码,并且可以在不修改父类的情况下进行功能扩展。
多态可以根据调用对象的不同而 ...
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准 https://blog.zysicyj.top
构造方法是一种特殊的方法,用于创建和初始化对象。它具有以下几个特点:
与类同名 :构造方法的名称必须与所在类的名称完全相同。
没有返回类型 :构造方法没有返回类型,包括 void。这是因为构造方法的主要目的是创建对象,而不是返回值。
可以重载 :一个类可以有多个构造方法,只要它们的参数列表不同即可。这样可以根据不同的需求来创建对象。
不能被继承或覆盖 :由于构造方法是用于创建对象的特殊方法,因此它们不能被继承或覆盖。子类可以调用父类的构造方法,但无法改变其实现。
默认构造方法 :如果一个类没有显式定义任何构造方法,编译器会自动提供一个默认构造方法。默认构造方法没有参数,并且执行空操作。
需要注意的是,虽然构造方法不能被继承或覆盖,但子类可以通过使用 super 关键字来调用父类的构造方法,并在其中添加额外的逻辑。这样可以确保父类的属性得到正确的初始化。
总结:
构造方法是用于创建和初始化对象的特殊方法。
构造方法与类 ...