6免费建站的网站,哔哩哔哩网页版下载视频,做电信网站运营商,做物理的网站文章目录 面向对象高级Object类的常用方法常用方法一#xff08;面向对象阶段#xff09;** 和 equals 的区别** 关键字native**单例设计模式#xff08;Singleton#xff09;**前情回顾#xff08;学习基础#xff09;静态修饰符Static设计模式概念开发步骤**两种实现方… 文章目录 面向对象高级Object类的常用方法常用方法一面向对象阶段** 和 equals 的区别** 关键字native**单例设计模式Singleton**前情回顾学习基础静态修饰符Static设计模式概念开发步骤**两种实现方式****饿汉式****懒汉式** **单例设计模式的线程安全问题** main方法分析public static void main(String[] args)命令行参数以及IDEA如何设置使用终端运行 实例变量赋值顺序**总结···类的加载顺序**分析 关键字final关键字final的意义**关键字 final 用于声明不可变的实体包括类、方法和变量。**final 关键字的使用场景 关键字abstract抽象类或抽象方法**关键字 abstract 用于声明抽象类和抽象方法** 模板设计模式概念细节分析 关键字interface接口**interface关键字的详细信息** **接口interface和抽象类abstract class**枚举类内部类四种类型 Annotation注解和元注解JUnit单元测试Test包装类用途介绍包装类和基本数据类型之间的转换**注意事项**包装类缓存优化Java中常用数据的缓存技术***包装类与基本数据类型的比较大小*** 面向对象高级
Object类的常用方法
常用方法一面向对象阶段
clone() 方法 clone() 方法用于创建并返回当前对象的一个副本克隆。要使用该方法类必须实现 Cloneable 接口并重写 clone() 方法。Cloneable 接口是一个标记接口它没有任何方法只是用于标识该类可以被克隆。在实现类中重写 clone() 方法时通常需要调用 super.clone() 方法来获得对象的浅拷贝副本然后根据需要进行深拷贝。默认情况下clone() 方法执行的是浅拷贝即复制对象的字段值但不复制引用对象本身。如果需要实现深拷贝需要在 clone() 方法中对引用对象进行单独的拷贝操作。 finalize() 方法 finalize() 方法是垃圾回收器在销毁对象之前调用的方法。垃圾回收器Garbage Collector负责回收不再使用的对象但在回收对象之前会调用对象的 finalize() 方法进行一些清理操作。默认实现的 finalize() 方法为空但可以在子类中重写该方法以定义对象在被销毁之前的清理行为如关闭文件、释放资源等。注意由于垃圾回收的时机不确定无法保证 finalize() 方法的及时执行因此不应该过于依赖该方法来释放资源而应该使用显式的资源释放方法如 close()来确保资源的及时释放。 toString() 方法 toString() 方法返回表示对象的字符串表示。在打印对象时通常会自动调用该方法来获取对象的字符串表示并输出到控制台。默认实现返回一个由类名、 符号和对象的哈希码组成的字符串。可以在类中重写 toString() 方法以返回更有意义的对象描述。通常重写的 toString() 方法会返回对象的属性值以及其他有用信息的字符串表示。 equals() 方法 equals() 方法用于比较两个对象是否相等。默认情况下equals() 方法比较的是对象的引用是否相等即两个对象是否指向同一个内存地址。通过重写 equals() 方法可以改变相等的定义。通常重写的 equals() 方法会比较对象的属性值判断它们是否相等。在重写 equals() 方法时通常还需要重写 hashCode() 方法以保证在使用基于哈希的集合类如 HashMap、HashSet时能够正确地比较和存储对象。 重写 equals() 方法原则对称性Symmetry 如果x.equals(y)返回true那么y.equals(x)也应该返回true。自反性Reflexivity x.equals(x)必须返回true。传递性Transitivity 如果x.equals(y)返回true且y.equals(z)返回true那么z.equals(x)也应该返回true。一致性Consistency 如果x.equals(y)返回true只要x和y的内容不变无论重复多少次调用x.equals(y)都应该返回true。非空性Non-nullity x.equals(null)应该始终返回false。类型检查Type check x.equals(obj)中如果obj的类型与x不同应该始终返回false。 和 equals 的区别 运算符既可以用于比较基本类型的值也可以用于比较引用类型的内存地址。对于基本类型它比较的是值是否相等对于引用类型它比较的是引用是否指向同一个对象即内存地址是否相等。equals() 方法是 java.lang.Object 类中定义的方法如果没有在自定义类中重写该方法那么默认的行为就是使用 运算符进行引用相等性的比较。然而许多类如 String会重写 equals() 方法以便根据对象的值来确定相等性而不仅仅是引用的比较。这可能导致一些误解使人误认为 equals() 方法在所有情况下都比较值。在自定义类中如果需要比较对象的相等性通常需要重写 equals() 方法并根据类的属性来确定相等性。这样可以根据具体需求定义对象相等的条件
区别点equals定义 是一个操作符用于比较两个变量的值是否相等equals 是一个方法用于比较两个对象的内容是否相等适用类型适用于基本数据类型和对象引用。适用于对象比较方式比较操作数的值比较操作数所引用的对象的内容返回值true 如果两个操作数的值相等否则返回 falsetrue 如果两个对象的内容相等否则返回 false重载 不能被重载equals 方法可以被重载
需要根据具体情况选择使用哪种比较方式。
对于基本类型优先使用 。对于对象优先使用 equals()除非只想检查是否引用同一个对象然后才使用 。
主要差别在于 只检查值。equals() 检查值和类型。
所以总的来说
使用 时要小心底层对象可能改变如 String 包装类Integer、Double等。优先使用 equals() 来判断对象的相等性。
关键字native
Java中的’ native 关键字用于表示方法是本机函数这意味着该方法是用Java以外的语言实现的例如C/ c并被编译成Java调用的DLL(动态链接库)。
下面是一些需要理解的关于原生方法的要点: 本机方法具有用不同的编程语言(通常是C或c)实现的主体。然而由于本机方法体的源代码不对我们开放我们无法看到它的实现。 在Java中定义本机方法时只声明其签名而不提供实现。
为什么使用本机方法?
虽然Java使用起来很方便但是有些任务在Java中不容易完成或者性能很关键。在这种情况下可以使用本机方法特别是在与低级操作系统或特定硬件交互时。本机方法提供了一个简洁的接口来执行这些任务而不必深入研究Java领域之外的复杂细节。
本机方法可以像任何其他Java方法一样被调用者使用
本机方法的存在不会影响调用这些方法的其他类。实际上调用这些方法的其他类甚至可能不知道它们正在调用本机方法。JVM处理调用本机方法的所有细节。
总之Java中的本机方法提供了一种方法可以将用其他语言实现的功能合并到Java程序中从而实现与低级操作或特定于硬件的任务的有效交互同时为应用程序的其余部分保持Java语言的便利性和简单性。
单例设计模式Singleton
前情回顾学习基础静态修饰符Static
设计模式概念
设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱不同的棋局我们用不同的棋谱。“套路”
经典的设计模式共有23种。每个设计模式均是特定环境下特定问题的处理方法。 简单工厂模式并不是23中经典模式的一种是其中工厂方法模式的简化版 开发步骤
单例设计模式是一种创建型设计模式它确保一个类只有一个实例并提供一个全局访问点来访问该实例。
在单例模式中类的构造函数是私有的这样外部无法直接实例化该类。而通过一个静态方法或静态变量类提供了对唯一实例的访问。
单例模式的主要特点包括
私有构造函数将类的构造器的访问权限设置为私有private这样外部无法通过构造函数直接创建类的实例。静态实例变量在类内部创建一个私有静态实例变量用于保存唯一的实例。提供一个公共的静态访问方法例如 getInstance()用于获取单例实例。在该方法内部进行逻辑判断如果实例变量为空则创建一个新的实例并赋值给实例变量。随后的调用都直接返回已创建的实例。
两种实现方式
饿汉式
特点立即加载即在使用类的时候已经将对象创建完毕。优点实现起来简单没有多线程安全问题。缺点当类被加载的时候会初始化static的实例静态变量被创建并分配内存空间从这以后这个static的实例便一直占着这块内存直到类被卸载时静态变量被摧毁并释放所占有的内存。因此在某些特定条件下会耗费内存。
class Singleton {// 1.私有化构造器private Singleton() {}// 2.内部提供一个当前类的实例// 4.此实例也必须静态化private static Singleton single new Singleton();// 3.提供公共的静态的方法返回当前类的对象public static Singleton getInstance() {return single;}
}懒汉式
特点延迟加载即在调用静态方法时实例才被创建。优点实现起来比较简单当类被加载的时候static的实例未被创建并分配内存空间当静态方法第一次被调用时初始化实例变量并分配内存因此在某些特定条件下会节约内存。缺点在多线程环境中这种实现方法是完全错误的线程不安全根本不能保证单例的唯一性。 说明在多线程章节会将懒汉式改造成线程安全的模式。
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关键字、双重检查锁定、静态内部类等机制来确保只有一个实例被创建并提供线程安全的访问方式。
懒汉式单例模式 懒汉式单例模式指的是在首次使用时才创建实例。当多个线程同时调用获取实例的方法时可能会导致创建多个实例的问题。若不考虑线程安全可能出现以下情况 线程A进入获取实例的方法发现实例为空创建一个实例。线程B也进入获取实例的方法此时实例仍为空线程B也创建一个实例。最终导致多个线程创建了多个实例违背了单例模式的原则。 解决线程安全问题的方法包括 在获取实例的方法上添加synchronized关键字使用同步锁保证只有一个线程能够进入临界区但会降低性能。使用双重检查锁定Double-Checked Locking机制即在同步块内再进行一次实例是否为空的检查这样可以避免每次都进入同步块。 饿汉式单例模式 饿汉式单例模式指的是在类加载时就创建实例。由于实例在类加载时就已经创建因此不存在并发创建多个实例的问题。饿汉式单例模式是线程安全的但可能存在性能问题因为实例在类加载时就创建无论是否使用都会占用内存。 双重检查锁定Double-Checked Locking 双重检查锁定是一种在懒汉式单例模式中解决线程安全问题的常用方法。通过在获取实例的方法内使用双重检查锁定机制可以避免每次都进入同步块提高性能。在双重检查锁定中需要注意使用volatile关键字修饰实例变量以确保多线程环境下的可见性和有序性。 静态内部类单例模式 静态内部类单例模式是一种常用的线程安全的单例模式实现方式。在静态内部类中创建单例实例由于静态内部类只在需要时才会被加载因此实现了懒加载的效果。静态内部类单例模式是线程安全的因为静态内部类的加载是线程安全的并且只会加载一次。
main方法
分析public static void main(String[] args)
在Java中程序的入口点是main()方法。为了使JVM能够调用main()方法它必须具有以下特征
访问权限必须是publicmain()方法必须声明为public以便JVM能够访问它。方法必须是staticmain()方法必须声明为static因为在调用main()方法时JVM无需创建类的实例。方法参数main()方法接受一个String类型的数组参数通常命名为args该数组保存执行Java命令时传递给程序的参数。
命令行参数以及IDEA如何设置使用终端运行
实例变量赋值顺序 总结···类的加载顺序
类的加载顺序 在创建子类对象时会先加载父类然后再加载子类。静态初始化块按照它们在代码中的顺序执行先执行父类的静态初始化块然后执行子类的静态初始化块。普通初始化块和构造方法按照它们在代码中的顺序执行先执行父类的普通初始化块和构造方法然后执行子类的普通初始化块和构造方法。
分析
静态初始化块static代码块 静态初始化块在类加载时执行且只执行一次。静态初始化块按照它们在代码中的顺序执行。静态初始化块用于初始化类级别的静态成员变量或执行其他静态操作。 普通初始化块初始化代码块 普通初始化块在创建对象时执行每次创建对象都会执行一次。普通初始化块按照它们在代码中的顺序执行在构造方法之前执行。普通初始化块用于初始化实例级别的成员变量或执行其他实例级别的操作。 构造方法 构造方法在创建对象时执行用于完成对象的初始化。构造方法可以重载通过不同的参数列表来区分。在构造方法中可以通过super()调用超类的构造方法或者通过this()调用同一类中的其他构造方法。
关键字final
关键字final的意义
不可修改性final 可以将实体声明为不可修改的确保其数值或行为不会被改变。安全性和稳定性final 可以提供代码的安全性和稳定性防止意外的修改和不必要的变动。性能优化final 可以用于性能优化编译器可以进行更多的优化提高执行效率。API 设计在设计 API 时使用 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 关键字声明的类。抽象类不能被实例化即不能创建抽象类的对象。抽象类可以包含抽象方法、普通方法、静态方法、构造方法和成员变量。抽象类可以有构造方法但不能直接通过构造方法创建对象只能通过其子类来创建对象。抽象类可以拥有抽象方法和非抽象方法的具体实现。抽象类可以被继承子类需要实现抽象类中的所有抽象方法或声明自身为抽象类。 抽象方法 抽象方法是用 abstract 关键字声明的方法没有方法体。抽象方法在抽象类中声明子类必须实现抽象方法。抽象方法用于定义方法的接口具体的实现由子类提供。子类继承抽象类后必须实现父类中的所有抽象方法除非子类也是抽象类。抽象方法不能是私有、静态、final 或 native。 抽象类和抽象方法的作用 抽象类提供了一种模板或基础用于派生具体子类。抽象类可以定义抽象方法强制子类实现这些方法确保方法在各个子类中的一致性。抽象类可以包含具体的方法实现提供通用的功能或默认的行为。抽象类可以作为多态的基础通过父类引用指向子类对象。
模板设计模式
概念
模板设计模式Template Design Pattern是一种行为型设计模式用于定义算法的框架结构将算法的具体实现延迟到子类中。模板设计模式通过定义一个抽象类或接口作为算法的模板并在其中定义算法的骨架而将一些具体步骤的实现延迟到子类中。
在模板设计模式中通常包含以下角色
抽象类Abstract Class抽象类定义了算法的模板其中包含了算法的骨架和一些抽象方法或钩子方法。抽象类负责控制算法的执行流程并定义了算法中不变的部分。具体类Concrete Class具体类是抽象类的子类实现了抽象方法或钩子方法完成算法中可变的部分。具体类实现了抽象类中定义的算法模板并提供了具体的实现细节。
细节分析 角色 模板Template定义了算法的骨架包含一个或多个抽象方法用于延迟实现的步骤。具体模板Concrete Template实现了模板中定义的抽象方法完成算法中的具体步骤。 工作原理 模板设计模式通过定义一个模板方法来实现算法的骨架。模板方法包含了算法的主要逻辑它调用了多个抽象方法和具体方法。抽象方法由模板定义用于延迟实现的步骤。具体方法在模板中有默认的实现也可以由子类进行重写。子类通过继承模板并实现其中的抽象方法来完成算法的具体实现。 优点 提供了一种封装算法的方式使得算法的骨架可以在不改变结构的情况下进行扩展和修改。遵循了开闭原则模板方法定义了算法的骨架具体实现可以在子类中进行扩展而不需要修改模板方法本身。通过模板方法的定义和抽象方法的实现实现了算法的复用和代码的共享。
关键字interface接口
interface关键字的详细信息
声明接口 使用interface关键字来声明接口。接口的名称应该采用大写字母开头的驼峰命名法。 方法声明 接口中的方法只有方法签名没有具体的实现。方法声明包括方法的返回类型、方法名和参数列表。方法默认为公共的public可以省略访问修饰符。 常量声明 接口中可以定义常量常量被隐式声明为public static final。常量的命名应该使用全大写字母和下划线的命名规范。 默认方法Default Methods 从Java 8开始接口可以包含默认方法使用default关键字进行声明和实现。默认方法提供了接口的默认实现实现类可以直接使用或重写默认方法。默认方法可以通过接口的实例调用也可以在实现类中被调用。 静态方法Static Methods 从Java 8开始接口可以包含静态方法使用static关键字进行声明和实现。静态方法是接口的类级别方法可以直接通过接口名调用无需实例化接口。 继承接口Interface Inheritance 接口可以继承其他接口使用extends关键字。一个接口可以继承多个接口采用逗号分隔。继承的接口中的方法和常量会被继承到子接口中。 实现接口Interface Implementation 类可以通过使用implements关键字来实现接口。实现接口要求类提供接口中定义的所有方法的具体实现。类可以实现多个接口使用逗号分隔。 接口与抽象类Interface vs Abstract Class 接口只能包含常量和方法声明没有字段和具体实现。抽象类可以包含字段、方法和具体实现。类可以实现多个接口但只能继承一个抽象类。 接口的使用场景 定义契约和协议规范类的行为和能力。实现多态允许一个类实现多个接口。跳转接口的多态接口隔离将系统功能进行拆分降低类之间的耦合度。规范约束提供代码的规范和可读性。
接口interface和抽象类abstract class
特点接口 (interface)抽象类 (abstract class)实例化不能实例化不能实例化构造函数不能包含构造函数可以包含构造函数字段不能包含字段可以包含字段方法只包含方法声明没有方法实现可以包含方法声明和方法实现多继承支持多继承不支持多继承单继承可以继承多个接口只能继承一个抽象类默认方法可以包含默认方法不支持默认方法静态方法可以包含静态方法可以包含静态方法访问修饰符默认为公共public可以使用各种访问修饰符构建范围用于定义契约和协议规范类的行为和能力用于抽象概念和部分实现提供共享代码和行为的能力实现方式类实现接口时使用implements关键字类继承抽象类时使用extends关键字设计目的接口隔离实现多态提供共享代码和行为的能力提供抽象概念实例化要求类要实现接口中定义的所有方法类可以选择性地实现抽象类中的方法常见设计模式简单工厂、工厂方法、代理模式模板方法设计模式
枚举类
内部类
四种类型
内部类是指在一个类的内部定义的类。Java中的内部类有四种类型成员内部类、静态内部类、局部内部类和匿名内部类。
成员内部类Member Inner Class 定义成员内部类是定义在类的内部并且与类的成员变量和方法同级别的类。特点 成员内部类可以访问外部类的所有成员变量和方法包括私有成员。成员内部类可以使用访问控制修饰符进行修饰public、private等。成员内部类的实例必须依赖于外部类的实例即需要通过外部类的实例来创建内部类的对象。 使用情况 成员内部类适合用于需要访问外部类的成员变量和方法并且与外部类有密切关联的情况。 静态内部类Static Inner Class 定义静态内部类是定义在类的内部但使用 static 关键字修饰的类。特点 静态内部类与外部类的实例无关可以直接创建静态内部类的对象。静态内部类可以访问外部类的静态成员变量和方法但不能直接访问外部类的非静态成员。静态内部类可以拥有自己的静态成员变量和方法。 使用情况 静态内部类适合用于与外部类没有紧密关联的情况或者需要创建独立于外部类实例的对象的情况。 局部内部类Local Inner Class 定义局部内部类是定义在方法内部的类。特点 局部内部类只在所在方法中可见外部方法无法访问局部内部类。局部内部类可以访问方法中的 final 或 effectively final 的局部变量。局部内部类不能声明静态成员变量和方法。 使用情况 局部内部类适合用于需要在方法内部定义一个辅助类且该类只在该方法内部使用的情况。 匿名内部类Anonymous Inner Class 定义匿名内部类是没有显式定义类名的内部类通常直接作为参数或方法内部的一部分来使用。特点 匿名内部类没有类名直接定义在方法内部或作为参数传递。匿名内部类可以继承一个类或实现一个接口。匿名内部类可以访问外部类的成员变量和方法以及方法中的 final 或 effectively final 的局部变量。 使用情况 匿名内部类适合用于需要定义一次性的类不需要命名或重复使用的情况比如创建事件处理器、实现接口等。
Annotation注解和元注解
JUnit单元测试Test
包装类
用途
编码过程中只接收对象的情况比如List中只能存入对象不能存入基本数据类型比如一个方法的参数是Object时不能传入基本数据类型但可以传入对应的包装类 比如泛型等等。基本数据类型没有toString()方法等
介绍
包装类Wrapper Class是Java中提供的一组类用于将基本数据类型如int、char、boolean等封装成对象。每种基本数据类型都有对应的包装类包装类提供了许多方法和功能使得基本数据类型可以像对象一样进行操作。
特点和功能 封装包装类将基本数据类型封装成对象使其具有对象的特性如可以作为方法的参数和返回值可以参与对象的存储和传递等。自动装箱和拆箱Java提供了自动装箱和拆箱机制可以自动在基本数据类型和对应的包装类之间进行转换。不可变性包装类的实例是不可变的即一旦创建就无法修改其值。包装类提供了许多方法用于操作和处理基本数据类型如比较、转换、格式化等。包装类还提供了常量和静态方法如最大值、最小值、类型转换等。
包装类和基本数据类型之间的转换
自动装箱Autoboxing 自动装箱是指将基本数据类型自动转换为对应的包装类对象。 自动拆箱Unboxing 自动拆箱是指将包装类对象自动转换为对应的基本数据类型。 包装类提供的方法进行转换 valueOf()方法用于将基本数据类型转换为对应的包装类对象。xxxValue()方法用于将包装类对象转换为基本数据类型的值。parseXxx()方法用于将字符串转换为基本数据类型的值。
注意事项
在进行包装类与基本数据类型之间的比较时应使用包装类提供的 equals() 方法而不是直接使用 “” 进行比较。在使用自动拆箱时需要确保包装类对象不为 null否则会抛出 NullPointerException 异常。
包装类缓存优化Java中常用数据的缓存技术
Java对部分经常使用的数据采用缓存技术在类第一次被加载时创建缓存和数据。当使用等值对象时直接从缓存中获取从而提高了程序执行性能通常只对常用数据进行缓存。
包装类与基本数据类型的比较大小
在Java中包装类与基本数据类型之间可以进行相等性比较。对于基本数据类型可以直接使用关系运算符如、、等进行比较。而对于包装类则需要使用equals()方法进行比较。
在某些情况下使用valueOf()方法创建的包装类对象可以利用缓存技术使得在一定范围内的比较结果为相等。
各个包装类的缓存范围和一些特殊注意事项
Integer类型有缓存-128到127的对象。缓存上限可以通过配置JVM参数来更改。Byte、Short、Long类型有缓存-128到127的对象。Character缓存0到127的对象。Boolean缓存TRUE和FALSE的对象。
需要注意的是只有使用valueOf()方法构造对象时才会使用缓存。使用new方法等方式创建对象不会使用缓存。
故当使用valueOf()方法创建包装类对象时与基本数据类型进行大小比较时在缓存范围内的值将被认为是相等的。这是因为它们引用了缓存中的同一个对象。