clone() 方法:
clone() 方法用于创建并返回当前对象的一个副本(克隆)。要使用该方法,类必须实现 Cloneable 接口,并重写 clone() 方法。Cloneable 接口是一个标记接口,它没有任何方法,只是用于标识该类可以被克隆。clone() 方法时,通常需要调用 super.clone() 方法来获得对象的浅拷贝副本,然后根据需要进行深拷贝。clone() 方法执行的是浅拷贝,即复制对象的字段值,但不复制引用对象本身。如果需要实现深拷贝,需要在 clone() 方法中对引用对象进行单独的拷贝操作。finalize() 方法:
finalize() 方法是垃圾回收器在销毁对象之前调用的方法。finalize() 方法进行一些清理操作。finalize() 方法为空,但可以在子类中重写该方法,以定义对象在被销毁之前的清理行为,如关闭文件、释放资源等。finalize() 方法的及时执行,因此不应该过于依赖该方法来释放资源,而应该使用显式的资源释放方法(如 close())来确保资源的及时释放。toString() 方法:
toString() 方法返回表示对象的字符串表示。@ 符号和对象的哈希码组成的字符串。toString() 方法,以返回更有意义的对象描述。通常,重写的 toString() 方法会返回对象的属性值以及其他有用信息的字符串表示。equals() 方法:
equals() 方法用于比较两个对象是否相等。equals() 方法比较的是对象的引用是否相等,即两个对象是否指向同一个内存地址。equals() 方法,可以改变相等的定义。通常,重写的 equals() 方法会比较对象的属性值,判断它们是否相等。equals() 方法时,通常还需要重写 hashCode() 方法,以保证在使用基于哈希的集合类(如 HashMap、HashSet)时能够正确地比较和存储对象。
equals() 方法原则x.equals(y)返回true,那么y.equals(x)也应该返回true。x.equals(x)必须返回true。x.equals(y)返回true,且y.equals(z)返回true,那么z.equals(x)也应该返回true。x.equals(y)返回true,只要x和y的内容不变,无论重复多少次调用x.equals(y),都应该返回true。x.equals(null)应该始终返回false。x.equals(obj)中,如果obj的类型与x不同,应该始终返回false。== 运算符既可以用于比较基本类型的值,也可以用于比较引用类型的内存地址。对于基本类型,它比较的是值是否相等;对于引用类型,它比较的是引用是否指向同一个对象(即内存地址是否相等)。equals() 方法是 java.lang.Object 类中定义的方法,如果没有在自定义类中重写该方法,那么默认的行为就是使用 == 运算符进行引用相等性的比较。然而,许多类(如 String)会重写 equals() 方法,以便根据对象的值来确定相等性,而不仅仅是引用的比较。这可能导致一些误解,使人误认为 equals() 方法在所有情况下都比较值。equals() 方法,并根据类的属性来确定相等性。这样可以根据具体需求定义对象相等的条件| 区别点 | == | equals |
|---|---|---|
| 定义 | == 是一个操作符,用于比较两个变量的值是否相等 | equals 是一个方法,用于比较两个对象的内容是否相等 |
| 适用类型 | 适用于基本数据类型和对象引用。 | 适用于对象 |
| 比较方式 | 比较操作数的值 | 比较操作数所引用的对象的内容 |
| 返回值 | true 如果两个操作数的值相等,否则返回 false | true 如果两个对象的内容相等,否则返回 false |
| 重载 | == 不能被重载 | equals 方法可以被重载 |
需要根据具体情况选择使用哪种比较方式。
==。equals(),除非只想检查是否引用同一个对象,然后才使用 ==。主要差别在于:
== 只检查值。equals() 检查值和类型。所以总的来说:
== 时要小心底层对象可能改变(如 String 包装类Integer、Double等)。equals() 来判断对象的相等性。Java中的’ native '关键字用于表示方法是本机函数,这意味着该方法是用Java以外的语言实现的,例如C/ c++,并被编译成Java调用的DLL(动态链接库)。
下面是一些需要理解的关于原生方法的要点:
本机方法具有用不同的编程语言(通常是C或c++)实现的主体。然而,由于本机方法体的源代码不对我们开放,我们无法看到它的实现。
在Java中定义本机方法时,只声明其签名而不提供实现。
为什么使用本机方法?
虽然Java使用起来很方便,但是有些任务在Java中不容易完成,或者性能很关键。在这种情况下,可以使用本机方法,特别是在与低级操作系统或特定硬件交互时。本机方法提供了一个简洁的接口来执行这些任务,而不必深入研究Java领域之外的复杂细节。
本机方法可以像任何其他Java方法一样被调用者使用
本机方法的存在不会影响调用这些方法的其他类。实际上,调用这些方法的其他类甚至可能不知道它们正在调用本机方法。JVM处理调用本机方法的所有细节。
总之,Java中的本机方法提供了一种方法,可以将用其他语言实现的功能合并到Java程序中,从而实现与低级操作或特定于硬件的任务的有效交互,同时为应用程序的其余部分保持Java语言的便利性和简单性。
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。“套路”
经典的设计模式共有23种。每个设计模式均是特定环境下特定问题的处理方法。

简单工厂模式并不是23中经典模式的一种,是其中工厂方法模式的简化版
单例设计模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
在单例模式中,类的构造函数是私有的,这样外部无法直接实例化该类。而通过一个静态方法或静态变量,类提供了对唯一实例的访问。
单例模式的主要特点包括:
getInstance(),用于获取单例实例。在该方法内部进行逻辑判断,如果实例变量为空,则创建一个新的实例并赋值给实例变量。随后的调用都直接返回已创建的实例。立即加载,即在使用类的时候已经将对象创建完毕。简单;没有多线程安全问题。耗费内存。class Singleton {
// 1.私有化构造器
private Singleton() {
}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single = new Singleton();
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
return single;
}
}
延迟加载,即在调用静态方法时实例才被创建。节约内存。线程不安全,根本不能保证单例的唯一性。
class Singleton {
// 1.私有化构造器
private Singleton() {
}
// 2.内部提供一个当前类的实例
// 4.此实例也必须静态化
private static Singleton single;
// 3.提供公共的静态的方法,返回当前类的对象
public static Singleton getInstance() {
if(single == null) {
single = new Singleton();
}
return single;
}
}
(先看完线程同步,在回过头看这个内容)
单例设计模式在多线程环境下可能存在线程安全问题,特别是懒汉式单例模式。为了解决线程安全问题,可以使用synchronized关键字、双重检查锁定、静态内部类等机制来确保只有一个实例被创建,并提供线程安全的访问方式。
synchronized关键字,使用同步锁保证只有一个线程能够进入临界区,但会降低性能。volatile关键字修饰实例变量,以确保多线程环境下的可见性和有序性。在Java中,程序的入口点是main()方法。为了使JVM能够调用main()方法,它必须具有以下特征:
public:main()方法必须声明为public,以便JVM能够访问它。static:main()方法必须声明为static,因为在调用main()方法时,JVM无需创建类的实例。main()方法接受一个String类型的数组参数(通常命名为args),该数组保存执行Java命令时传递给程序的参数。
static代码块):
super()调用超类的构造方法,或者通过this()调用同一类中的其他构造方法。final 可以将实体声明为不可修改的,确保其数值或行为不会被改变。final 可以提供代码的安全性和稳定性,防止意外的修改和不必要的变动。final 可以用于性能优化,编译器可以进行更多的优化,提高执行效率。final 可以提供清晰的接口定义,减少对外部代码的依赖,促进代码的可维护性。final 用于声明不可变的实体,包括类、方法和变量。final 类:
final 的类**不能被继承**,即它是最终类。final 类中的方法默认为 final,但可以被子类继承,除非它们被子类重写并标记为 final。final 的类通常用于安全性、稳定性或效率等方面的考虑。final 方法:
final 的方法不能被子类重写或覆盖。final 方法在父类中定义实现,并且子类不能对其进行更改。final 方法可以被继承,但无法被子类修改。final 变量:
final 的变量是一个常量,一旦赋予初始值后,就不能再改变。final 变量必须在声明时初始化,可以通过直接赋值或构造方法进行初始化。final 变量通常使用大写字母表示,并使用下划线分隔单词(例如:MAX_SIZE)。final 变量可以是基本数据类型(如 int、char 等)或引用类型(如 String、Object 等)。final 变量,引用本身是不可变的,但是对象的内部状态仍然可以修改。final 参数:
final 的方法参数表示该参数在方法内部不可修改。final 参数可以确保方法中不会意外地修改参数的值。final 和继承:
final 的类不能被继承。final 的方法不能被子类重写。final 的变量在被赋值后不能再修改。final 关键字的使用场景包括但不限于以下几种情况:
abstract 用于声明抽象类和抽象方法abstract 关键字声明的类。abstract 关键字声明的方法,没有方法体。模板设计模式(Template Design Pattern)是一种行为型设计模式,用于定义算法的框架结构,将算法的具体实现延迟到子类中。模板设计模式通过定义一个抽象类或接口作为算法的模板,并在其中定义算法的骨架,而将一些具体步骤的实现延迟到子类中。
在模板设计模式中,通常包含以下角色:
角色:
工作原理:
优点:
interface关键字的详细信息interface关键字来声明接口。public),可以省略访问修饰符。public static final。default关键字进行声明和实现。static关键字进行声明和实现。extends关键字。implements关键字来实现接口。| 特点 | 接口 (interface) | 抽象类 (abstract class) |
|---|---|---|
| 实例化 | 不能实例化 | 不能实例化 |
| 构造函数 | 不能包含构造函数 | 可以包含构造函数 |
| 字段 | 不能包含字段 | 可以包含字段 |
| 方法 | 只包含方法声明,没有方法实现 | 可以包含方法声明和方法实现 |
| 多继承 | 支持多继承 | 不支持多继承 |
| 单继承 | 可以继承多个接口 | 只能继承一个抽象类 |
| 默认方法 | 可以包含默认方法 | 不支持默认方法 |
| 静态方法 | 可以包含静态方法 | 可以包含静态方法 |
| 访问修饰符 | 默认为公共(public) | 可以使用各种访问修饰符 |
| 构建范围 | 用于定义契约和协议,规范类的行为和能力 | 用于抽象概念和部分实现,提供共享代码和行为的能力 |
| 实现方式 | 类实现接口时使用implements关键字 | 类继承抽象类时使用extends关键字 |
| 设计目的 | 接口隔离,实现多态 | 提供共享代码和行为的能力,提供抽象概念 |
| 实例化要求 | 类要实现接口中定义的所有方法 | 类可以选择性地实现抽象类中的方法 |
| 常见设计模式 | 简单工厂、工厂方法、代理模式 | 模板方法设计模式 |
内部类是指在一个类的内部定义的类。Java中的内部类有四种类型:成员内部类、静态内部类、局部内部类和匿名内部类。
包装类(Wrapper Class)是Java中提供的一组类,用于将基本数据类型(如int、char、boolean等)封装成对象。每种基本数据类型都有对应的包装类,包装类提供了许多方法和功能,使得基本数据类型可以像对象一样进行操作。
Java对部分经常使用的数据采用缓存技术,在类第一次被加载时创建缓存和数据。当使用等值对象时直接从缓存中获取,从而提高了程序执行性能(通常只对常用数据进行缓存)。
在Java中,包装类与基本数据类型之间可以进行相等性比较。对于基本数据类型,可以直接使用关系运算符(如>、<、==等)进行比较。而对于包装类,则需要使用equals()方法进行比较。
在某些情况下,使用valueOf()方法创建的包装类对象可以利用缓存技术,使得在一定范围内的比较结果为相等。
各个包装类的缓存范围和一些特殊注意事项:
需要注意的是,只有使用valueOf()方法构造对象时才会使用缓存。使用new方法等方式创建对象不会使用缓存。
故当使用valueOf()方法创建包装类对象时,与基本数据类型进行大小比较时,在缓存范围内的值将被认为是相等的。这是因为它们引用了缓存中的同一个对象。