Java面向对象高级

文章目录

  • 面向对象高级
    • 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() 方法,以保证在使用基于哈希的集合类(如 HashMapHashSet)时能够正确地比较和存储对象。
      • 重写 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,只要xy的内容不变,无论重复多少次调用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 包装类IntegerDouble等)。
  • 优先使用 equals() 来判断对象的相等性。

关键字native

Java中的’ native '关键字用于表示方法是本机函数,这意味着该方法是用Java以外的语言实现的,例如C/ c++,并被编译成Java调用的DLL(动态链接库)。

下面是一些需要理解的关于原生方法的要点:

  1. 本机方法具有用不同的编程语言(通常是C或c++)实现的主体。然而,由于本机方法体的源代码不对我们开放,我们无法看到它的实现。

  2. 在Java中定义本机方法时,只声明其签名而不提供实现。

为什么使用本机方法?

虽然Java使用起来很方便,但是有些任务在Java中不容易完成,或者性能很关键。在这种情况下,可以使用本机方法,特别是在与低级操作系统或特定硬件交互时。本机方法提供了一个简洁的接口来执行这些任务,而不必深入研究Java领域之外的复杂细节。

本机方法可以像任何其他Java方法一样被调用者使用

本机方法的存在不会影响调用这些方法的其他类。实际上,调用这些方法的其他类甚至可能不知道它们正在调用本机方法。JVM处理调用本机方法的所有细节。

总之,Java中的本机方法提供了一种方法,可以将用其他语言实现的功能合并到Java程序中,从而实现与低级操作或特定于硬件的任务的有效交互,同时为应用程序的其余部分保持Java语言的便利性和简单性。

单例设计模式(Singleton)

前情回顾(学习基础)静态修饰符Static

设计模式概念

设计模式是在大量的实践中总结理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。“套路”

经典的设计模式共有23种。每个设计模式均是特定环境下特定问题的处理方法。

在这里插入图片描述

简单工厂模式并不是23中经典模式的一种,是其中工厂方法模式的简化版

开发步骤

单例设计模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来访问该实例。

在单例模式中,类的构造函数是私有的,这样外部无法直接实例化该类。而通过一个静态方法或静态变量,类提供了对唯一实例的访问。

单例模式的主要特点包括:

  1. 私有构造函数:将类的构造器的访问权限设置为私有(private),这样外部无法通过构造函数直接创建类的实例。
  2. 静态实例变量:在类内部创建一个私有静态实例变量,用于保存唯一的实例。
  3. 提供一个公共的静态访问方法,例如 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关键字、双重检查锁定、静态内部类等机制来确保只有一个实例被创建,并提供线程安全的访问方式。

  1. 懒汉式单例模式:
    • 懒汉式单例模式指的是在首次使用时才创建实例。当多个线程同时调用获取实例的方法时,可能会导致创建多个实例的问题。
    • 若不考虑线程安全,可能出现以下情况:
      • 线程A进入获取实例的方法,发现实例为空,创建一个实例。
      • 线程B也进入获取实例的方法,此时实例仍为空,线程B也创建一个实例。
      • 最终导致多个线程创建了多个实例,违背了单例模式的原则。
    • 解决线程安全问题的方法包括:
      • 在获取实例的方法上添加synchronized关键字,使用同步锁保证只有一个线程能够进入临界区,但会降低性能。
      • 使用双重检查锁定(Double-Checked Locking)机制,即在同步块内再进行一次实例是否为空的检查,这样可以避免每次都进入同步块。
  2. 饿汉式单例模式:
    • 饿汉式单例模式指的是在类加载时就创建实例。由于实例在类加载时就已经创建,因此不存在并发创建多个实例的问题。
    • 饿汉式单例模式是线程安全的,但可能存在性能问题,因为实例在类加载时就创建,无论是否使用都会占用内存。
  3. 双重检查锁定(Double-Checked Locking):
    • 双重检查锁定是一种在懒汉式单例模式中解决线程安全问题的常用方法。
    • 通过在获取实例的方法内使用双重检查锁定机制,可以避免每次都进入同步块,提高性能。
    • 在双重检查锁定中,需要注意使用volatile关键字修饰实例变量,以确保多线程环境下的可见性和有序性。
  4. 静态内部类单例模式:
    • 静态内部类单例模式是一种常用的线程安全的单例模式实现方式。
    • 在静态内部类中创建单例实例,由于静态内部类只在需要时才会被加载,因此实现了懒加载的效果。
    • 静态内部类单例模式是线程安全的,因为静态内部类的加载是线程安全的,并且只会加载一次。

main方法

分析public static void main(String[] args)

在Java中,程序的入口点是main()方法。为了使JVM能够调用main()方法,它必须具有以下特征:

  1. 访问权限必须是publicmain()方法必须声明为public,以便JVM能够访问它。
  2. 方法必须是staticmain()方法必须声明为static,因为在调用main()方法时,JVM无需创建类的实例。
  3. 方法参数:main()方法接受一个String类型的数组参数(通常命名为args),该数组保存执行Java命令时传递给程序的参数。

命令行参数以及IDEA如何设置使用终端运行

实例变量赋值顺序

在这里插入图片描述

总结···类的加载顺序

  1. 类的加载顺序:
    • 在创建子类对象时,会先加载父类,然后再加载子类。
    • 静态初始化块按照它们在代码中的顺序执行,先执行父类的静态初始化块,然后执行子类的静态初始化块。
    • 普通初始化块和构造方法按照它们在代码中的顺序执行,先执行父类的普通初始化块和构造方法,然后执行子类的普通初始化块和构造方法。

分析

  1. 静态初始化块(static代码块):
    • 静态初始化块在类加载时执行,且只执行一次。
    • 静态初始化块按照它们在代码中的顺序执行。
    • 静态初始化块用于初始化类级别的静态成员变量或执行其他静态操作。
  2. 普通初始化块(初始化代码块):
    • 普通初始化块在创建对象时执行,每次创建对象都会执行一次。
    • 普通初始化块按照它们在代码中的顺序执行,在构造方法之前执行。
    • 普通初始化块用于初始化实例级别的成员变量或执行其他实例级别的操作。
  3. 构造方法:
    • 构造方法在创建对象时执行,用于完成对象的初始化。
    • 构造方法可以重载,通过不同的参数列表来区分。
    • 在构造方法中,可以通过super()调用超类的构造方法,或者通过this()调用同一类中的其他构造方法。

关键字final

关键字final的意义

  • 不可修改性:final 可以将实体声明为不可修改的,确保其数值或行为不会被改变。
  • 安全性和稳定性:final 可以提供代码的安全性和稳定性,防止意外的修改和不必要的变动。
  • 性能优化:final 可以用于性能优化,编译器可以进行更多的优化,提高执行效率。
  • API 设计:在设计 API 时,使用 final 可以提供清晰的接口定义,减少对外部代码的依赖,促进代码的可维护性。

关键字 final 用于声明不可变的实体,包括类、方法和变量。

  1. final 类:
    • 声明为 final 的类**不能被继承**,即它是最终类。
    • final 类中的方法默认为 final,但可以被子类继承,除非它们被子类重写并标记为 final
    • 声明为 final 的类通常用于安全性、稳定性或效率等方面的考虑。
  2. final 方法:
    • 声明为 final 的方法不能被子类重写或覆盖。
    • final 方法在父类中定义实现,并且子类不能对其进行更改。
    • final 方法可以被继承,但无法被子类修改
  3. final 变量:
    • 声明为 final 的变量是一个常量,一旦赋予初始值后,就不能再改变。
    • final 变量必须在声明时初始化,可以通过直接赋值或构造方法进行初始化。
    • final 变量通常使用大写字母表示,并使用下划线分隔单词(例如:MAX_SIZE)。
    • final 变量可以是基本数据类型(如 intchar 等)或引用类型(如 StringObject 等)。
    • 对于引用类型的 final 变量,引用本身是不可变的,但是对象的内部状态仍然可以修改。
  4. final 参数:
    • 声明为 final 的方法参数表示该参数在方法内部不可修改
    • 使用 final 参数可以确保方法中不会意外地修改参数的值。
  5. final 和继承:
    • 声明为 final 的类不能被继承。
    • 声明为 final 的方法不能被子类重写。
    • 声明为 final 的变量在被赋值后不能再修改。

final 关键字的使用场景

包括但不限于以下几种情况:

  • 希望确保类不被继承或方法不被重写。
  • 希望创建不可变的常量。
  • 希望避免参数在方法内部被修改。
  • 用于优化代码,例如在方法内部缓存计算结果。

关键字abstract(抽象类或抽象方法)

关键字 abstract 用于声明抽象类和抽象方法

  1. 抽象类:
    • 抽象类是用 abstract 关键字声明的类。
    • 抽象类不能被实例化,即不能创建抽象类的对象。
    • 抽象类可以包含抽象方法、普通方法、静态方法、构造方法和成员变量。
    • 抽象类可以有构造方法,但不能直接通过构造方法创建对象,只能通过其子类来创建对象。
    • 抽象类可以拥有抽象方法和非抽象方法的具体实现。
    • 抽象类可以被继承,子类需要实现抽象类中的所有抽象方法或声明自身为抽象类。
  2. 抽象方法:
    • 抽象方法是用 abstract 关键字声明的方法,没有方法体
    • 抽象方法在抽象类中声明,子类必须实现抽象方法。
    • 抽象方法用于定义方法的接口,具体的实现由子类提供。
    • 子类继承抽象类后,必须实现父类中的所有抽象方法,除非子类也是抽象类。
    • 抽象方法不能是私有、静态、final 或 native。
  3. 抽象类和抽象方法的作用:
    • 抽象类提供了一种模板或基础,用于派生具体子类。
    • 抽象类可以定义抽象方法,强制子类实现这些方法,确保方法在各个子类中的一致性。
    • 抽象类可以包含具体的方法实现,提供通用的功能或默认的行为。
    • 抽象类可以作为多态的基础,通过父类引用指向子类对象。

模板设计模式

概念

模板设计模式(Template Design Pattern)是一种行为型设计模式,用于定义算法的框架结构,将算法的具体实现延迟到子类中。模板设计模式通过定义一个抽象类或接口作为算法的模板,并在其中定义算法的骨架,而将一些具体步骤的实现延迟到子类中。

在模板设计模式中,通常包含以下角色:

  1. 抽象类(Abstract Class):抽象类定义了算法的模板,其中包含了算法的骨架和一些抽象方法或钩子方法。抽象类负责控制算法的执行流程,并定义了算法中不变的部分。
  2. 具体类(Concrete Class):具体类是抽象类的子类,实现了抽象方法或钩子方法,完成算法中可变的部分。具体类实现了抽象类中定义的算法模板,并提供了具体的实现细节。

细节分析

  1. 角色:

    • 模板(Template):定义了算法的骨架,包含一个或多个抽象方法,用于延迟实现的步骤。
    • 具体模板(Concrete Template):实现了模板中定义的抽象方法,完成算法中的具体步骤。
  2. 工作原理:

    • 模板设计模式通过定义一个模板方法来实现算法的骨架。模板方法包含了算法的主要逻辑,它调用了多个抽象方法和具体方法。
    • 抽象方法由模板定义,用于延迟实现的步骤。具体方法在模板中有默认的实现,也可以由子类进行重写。
    • 子类通过继承模板并实现其中的抽象方法来完成算法的具体实现。
  3. 优点:

    • 提供了一种封装算法的方式,使得算法的骨架可以在不改变结构的情况下进行扩展和修改。
    • 遵循了开闭原则,模板方法定义了算法的骨架,具体实现可以在子类中进行扩展,而不需要修改模板方法本身。
    • 通过模板方法的定义和抽象方法的实现,实现了算法的复用和代码的共享。

关键字interface(接口)

interface关键字的详细信息

  1. 声明接口:
    • 使用interface关键字来声明接口。
    • 接口的名称应该采用大写字母开头的驼峰命名法。
  2. 方法声明:
    • 接口中的方法只有方法签名,没有具体的实现。
    • 方法声明包括方法的返回类型、方法名和参数列表。
    • 方法默认为公共的(public),可以省略访问修饰符。
  3. 常量声明:
    • 接口中可以定义常量,常量被隐式声明为public static final
    • 常量的命名应该使用全大写字母和下划线的命名规范。
  4. 默认方法(Default Methods):
    • 从Java 8开始,接口可以包含默认方法,使用default关键字进行声明和实现。
    • 默认方法提供了接口的默认实现,实现类可以直接使用或重写默认方法。
    • 默认方法可以通过接口的实例调用,也可以在实现类中被调用。
  5. 静态方法(Static Methods):
    • 从Java 8开始,接口可以包含静态方法,使用static关键字进行声明和实现。
    • 静态方法是接口的类级别方法,可以直接通过接口名调用,无需实例化接口。
  6. 继承接口(Interface Inheritance):
    • 接口可以继承其他接口,使用extends关键字。
    • 一个接口可以继承多个接口,采用逗号分隔。
    • 继承的接口中的方法和常量会被继承到子接口中。
  7. 实现接口(Interface Implementation):
    • 类可以通过使用implements关键字来实现接口。
    • 实现接口要求类提供接口中定义的所有方法的具体实现。
    • 类可以实现多个接口,使用逗号分隔。
  8. 接口与抽象类(Interface vs Abstract Class):
    • 接口只能包含常量和方法声明,没有字段和具体实现。
    • 抽象类可以包含字段、方法和具体实现。
    • 类可以实现多个接口,但只能继承一个抽象类。
  9. 接口的使用场景:
    • 定义契约和协议,规范类的行为和能力。
    • 实现多态,允许一个类实现多个接口。(跳转接口的多态)
    • 接口隔离,将系统功能进行拆分,降低类之间的耦合度。
    • 规范约束,提供代码的规范和可读性。

接口(interface)和抽象类(abstract class)

特点接口 (interface)抽象类 (abstract class)
实例化不能实例化不能实例化
构造函数不能包含构造函数可以包含构造函数
字段不能包含字段可以包含字段
方法只包含方法声明,没有方法实现可以包含方法声明和方法实现
多继承支持多继承不支持多继承
单继承可以继承多个接口只能继承一个抽象类
默认方法可以包含默认方法不支持默认方法
静态方法可以包含静态方法可以包含静态方法
访问修饰符默认为公共(public)可以使用各种访问修饰符
构建范围用于定义契约和协议,规范类的行为和能力用于抽象概念和部分实现,提供共享代码和行为的能力
实现方式类实现接口时使用implements关键字类继承抽象类时使用extends关键字
设计目的接口隔离,实现多态提供共享代码和行为的能力,提供抽象概念
实例化要求类要实现接口中定义的所有方法类可以选择性地实现抽象类中的方法
常见设计模式简单工厂、工厂方法、代理模式模板方法设计模式

枚举类

内部类

四种类型

内部类是指在一个类的内部定义的类。Java中的内部类有四种类型:成员内部类、静态内部类、局部内部类和匿名内部类。

  1. 成员内部类(Member Inner Class):
    • 定义:成员内部类是定义在类的内部,并且与类的成员变量和方法同级别的类。
    • 特点:
      • 成员内部类可以访问外部类的所有成员变量和方法,包括私有成员。
      • 成员内部类可以使用访问控制修饰符进行修饰(public、private等)。
      • 成员内部类的实例必须依赖于外部类的实例,即需要通过外部类的实例来创建内部类的对象。
    • 使用情况:
      • 成员内部类适合用于需要访问外部类的成员变量和方法,并且与外部类有密切关联的情况。
  2. 静态内部类(Static Inner Class):
    • 定义:静态内部类是定义在类的内部,但使用 static 关键字修饰的类。
    • 特点:
      • 静态内部类与外部类的实例无关,可以直接创建静态内部类的对象。
      • 静态内部类可以访问外部类的静态成员变量和方法,但不能直接访问外部类的非静态成员。
      • 静态内部类可以拥有自己的静态成员变量和方法。
    • 使用情况:
      • 静态内部类适合用于与外部类没有紧密关联的情况,或者需要创建独立于外部类实例的对象的情况。
  3. 局部内部类(Local Inner Class):
    • 定义:局部内部类是定义在方法内部的类
    • 特点:
      • 局部内部类只在所在方法中可见,外部方法无法访问局部内部类。
      • 局部内部类可以访问方法中的 final 或 effectively final 的局部变量。
      • 局部内部类不能声明静态成员变量和方法。
    • 使用情况:
      • 局部内部类适合用于需要在方法内部定义一个辅助类,且该类只在该方法内部使用的情况。
  4. 匿名内部类(Anonymous Inner Class)
    • 定义:匿名内部类是没有显式定义类名的内部类,通常直接作为参数或方法内部的一部分来使用。
    • 特点:
      • 匿名内部类没有类名,直接定义在方法内部或作为参数传递。
      • 匿名内部类可以继承一个类或实现一个接口。
      • 匿名内部类可以访问外部类的成员变量和方法,以及方法中的 final 或 effectively final 的局部变量。
    • 使用情况:
      • 匿名内部类适合用于需要定义一次性的类,不需要命名或重复使用的情况,比如创建事件处理器、实现接口等。

Annotation(注解)和元注解

JUnit单元测试(@Test)

包装类

用途

  1. 编码过程中只接收对象的情况,比如List中只能存入对象,不能存入基本数据类型;比如一个方法的参数是Object时,不能传入基本数据类型,但可以传入对应的包装类; 比如泛型等等。
  2. 基本数据类型没有toString()方法等

介绍

包装类(Wrapper Class)是Java中提供的一组类,用于将基本数据类型(如int、char、boolean等)封装成对象。每种基本数据类型都有对应的包装类,包装类提供了许多方法和功能,使得基本数据类型可以像对象一样进行操作。

  1. 特点和功能:
    • 封装:包装类将基本数据类型封装成对象,使其具有对象的特性,如可以作为方法的参数和返回值,可以参与对象的存储和传递等。
    • 自动装箱和拆箱: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()方法创建包装类对象时,与基本数据类型进行大小比较时,在缓存范围内的值将被认为是相等的。这是因为它们引用了缓存中的同一个对象。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/142557.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

手把手教你,细说向开源项目递交代码的流程

系列文章目录 手把手教你安装Git&#xff0c;萌新迈向专业的必备一步 GIT命令只会抄却不理解&#xff1f;看完原理才能事半功倍&#xff01; 常用GIT命令详解&#xff0c;手把手让你登堂入室 GIT实战篇&#xff0c;教你如何使用GIT可视化工具 GIT使用需知&#xff0c;哪些操作…

信息安全:网络安全漏洞防护技术原理与应用.

信息安全&#xff1a;网络安全漏洞防护技术原理与应用. 网络安全漏洞又称为脆弱性&#xff0c;简称漏洞。漏洞一般是致使网络信息系统安全策略相冲突的缺陷&#xff0c;这种缺陷通常称为安全隐患。 安全漏洞的影响主要有机密性受损、完整性破坏、可用性降低、抗抵赖性缺失、可…

UE5 虚幻引擎 使用编辑器工具进行资产批处理操作 让你的工作效率指数级增长!!!

目录 0 引言1 编辑器工具蓝图1.1 介绍1.2 案例&#xff1a;批量设置静态网格体资产的LOD1.3 进阶用法 2 编辑器工具控件2.1 介绍2.2 案例&#xff1a;随机给场景中Actor添加Yaw旋转值 0 引言 官方教程视频 参考文章 参考视频 UE5提供了两种 编辑器工具 &#xff1a;编辑器工具…

【计算机网络】IP协议

目录 前言 IP协议 基本概念 IP协议格式 分片 16位标识 3位标志与13位片偏移 分片流程 网段划分 网络号和主机号 DHCP协议 CIDR划分方案 特殊的ip地址 ip地址数量限制 私有ip地址与公网ip地址 路由转发 前言 我们前面讲了HTTP/HTTPS协议和TCP/…

HTML5福利篇--使用Canvas画图

目录 一.Canvas元素 1.Canvas元素定义 2.使用JavaScript获取页面中的Canvas对象 二.绘制图形 1.绘制直线 2.绘制矩形 &#xff08;1&#xff09;rect() &#xff08;2&#xff09;strokeRect() &#xff08;3&#xff09;fillRect()和clearRect()函数 3.绘制圆弧 4.…

位图布隆过滤器

文章目录 位图&布隆过滤器1. 位图1.1位图概念1.2位图原理1.3位图实现1.4位图排序 2. 布隆过滤器2.1 引入布隆过滤器2.2 概念2.3 布隆过滤器插入2.4 布隆过滤器的查找2.5 布隆过滤器模拟实现2.6 布隆过滤器的删除2.7 布隆过滤器优缺点2.8 布隆过滤器使用场景 3. 海量数据问题…

比特币 ZK 赏金系列:第 2 部分——查找哈希冲突

在我们的零知识赏金 (ZKB) 系列的第二部分中&#xff0c;我们将其应用于解决哈希冲突难题。在这样的谜题中&#xff0c;两个不同的输入散列到相同的输出。此类赏金可用于&#xff1a; 充当煤矿中的金丝雀&#xff0c;给我们一个有价值的提醒。存在冲突是散列函数较弱的标志&…

合合信息、上海大学、华南理工大学发布业内首个古彝文编码“大字典” ,为古文字打造“身份证”

“乌蒙山连着山外山&#xff0c;月光洒向了响水滩。”近期在各大短视频平台爆火的《奢香夫人》你听过吗&#xff1f;奢香夫人是一位彝族“巾帼英雄”&#xff0c;这首同名歌曲早在2009年便已发布&#xff0c;如今突然“翻红”&#xff0c;不仅体现了大众对于少数民族文化高涨的…

Unity可视化Shader工具ASE介绍——1、ASE的介绍、安装和简单使用

大家好&#xff0c;我是阿赵&#xff0c;接下来我打算介绍一下Unity引擎的一个好用的可视化Shader编辑插件。这个插件叫做Amplify Shader Editor&#xff0c;下面都会简称为ASE。这一篇主要是讲一下这个插件的获取、安装&#xff0c;和一些简单的界面用法介绍。之后有机会&…

C语言的stdio.h的介绍

C语言的stdio.h的介绍 C语言的stdio.h的介绍 C语言的stdio.h的介绍C语言stdio.h的介绍 C语言stdio.h的介绍 这个含义是导入标准输入输出库 包含头文件.h&#xff0c;std标准库&#xff0c;io是input output输入输出库 <>代表系统库&#xff0c;自定义的话用""…

C++打印字符串数组中的元素(字符串)

C遍历字符串数组&#xff0c;在main函数里定义一个字符串数组&#xff0c;要求依次输出字符串元素&#xff1a; string a[4] {"a", "vag", "gwe", "gewa"};希望打印的结果 上面可以看做是二维指针&#xff0c;第一维是每个字符串&a…

Springboot 前后端分离项目使用 POI 生成并导出 Excel

在做一个 SpringBoot 前后端分离项目的时候&#xff0c;需要将数据存到 Excel中&#xff0c;用户可以下载 Excel。具体实现是采用 Apache 强大的 POI。文章最后将源码例出。 POI API 文档&#xff1a; https://poi.apache.org/apidocs/dev/index.html 步骤 导入 POI 的 maven …

【C语言】指针的进阶(三)—— 模拟实现qsort函数以及指针和数组的笔试题解析

目录 1、模拟实现qsort函数 1.1、qsort函数的回顾 1.2、模拟实现qsort函数 2、指针和数组笔试题解析 2.1、一维数组 2.2、字符数组 1、模拟实现qsort函数 1.1、qsort函数的回顾 要模拟实现qsort函数&#xff0c;就要了解清楚qsort函数的参数以及使用方式。 我们先回顾一…

vue3 - 封装倒计时函数 useCountDown

编写一个函数 useCountDown 可以把秒数格式化为倒计时的显示状态。 步骤 1. 编写函数框架 ---> 确认参数和返回值&#xff08;显示格式化时间的数据开启倒计时的函数&#xff09; 2. 倒计时的核心逻辑&#xff1a;每隔1s减一 3. 格式化 1&#xff09;安装格式化工具&#xf…

跨域问题的原理及解决方法

一.同源策略 如果没有进行特殊处理&#xff0c;我们在进行前后端联调的时候游览器会发生报错&#xff1a; 这是因为请求被同源策略被阻止&#xff0c;浏览器出于安全的考虑&#xff0c;使用XMLHttpRequest对象发起HTTP请求&#xff08;异步请求&#xff09;时必须遵守同源策略…

单文件制作工具 v7.0.2.38(20230406) 最新版_一个小巧强大的PECMD/7zSFX单文件制作工具

网盘下载 功能描述 —全新的自解压内核&#xff0c;非现有的7zSFX、WinRAR、ZLIB自解压模块&#xff1b; —采用先进的打包方式&#xff08;堪称黑科技—>内核默认PECMD自解压模块&#xff09; —7zSFX模块&#xff0c;创建的单文件支持传递参数&#xff08;包含内置参数和外…

1、MQ基础

微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中&#xff0c;调用者发起请求后需要等待服务提供者执行业务返回结果后&#xff0c;才能继续执行后面的业务。也就是说调用者在调用过程中处于…

信息安全:网络安全审计技术原理与应用.

信息安全&#xff1a;网络安全审计技术原理与应用. 网络安全审计是指对网络信息系统的安全相关活动信息进行获取、记录、存储、分析和利用的工作。网络安全审计的作用在千建立“事后“安全保障措施&#xff0c;保存网络安全事件及行为信息&#xff0c;为网络安全事件分析提供线…

SQLite 3.43 发布,性能大提升!

前言 SQLite是一种被广泛运用的嵌入式关系型数据库管理系统&#xff0c;最新发布的SQLite 3.43版本带来了一个重要的改进&#xff0c;大幅提升了对JSON数据的处理性能&#xff0c;达到了之前的两倍。 主要更新 添加对 Contentless-Delete FTS5 索引的支持。这是 FTS5 全文搜索…

leetcode算法题-移动零Java

这道题的解法,我们可以新建一个等长的数组,初始化后数组中的元素都为零,我们只需要遍历一遍原来的数组,将不为0的数据转移到新数组即可,下面是代码实现: public static void main(String[] args) {System.out.println("移动零:" Arrays.toString(moveZero(new int[…