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.mzph.cn/news/88400.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot集成quartz并实现定时任务管理

依赖&#xff1a; <quartz.version>2.3.0</quartz.version><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>${quartz.version}</version><exclusions><exclus…

“的修“报修工单管理系统有哪些功能和作用?

“的修"报修工单管理系统是基于微信平台的&#xff0c;无需下载和安装&#xff0c;只需扫码即可使用。它是一个维保过程管控的理想解决方案&#xff0c;适用于企业、学校、医院、物业等单位需要设备维保的场景。“的修"报修小程序具有独立部署和可控的数据安全性&…

手把手教你实现:将后端SpringBoot项目部署到华为云服务器上

前言 前提&#xff1a;有一个后端项目&#xff0c;项目能够运行在本地&#xff0c;可以通过本地访问&#xff08;localhost&#xff09; 如果没有可以看这篇&#xff1a;一个基于SpringBoot的后端项目 注册华为云账号 华为云官网 购买云服务器 产品 -> 华为云耀云服务器…

【数据结构-树】哈夫曼树

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…

图片编辑小程序源码/拼图小程序源码

图片编辑小程序源码&#xff0c;拼图小程序源码。全能、便捷的图片编辑工具。实现了图片裁剪、添加文字、涂鸦、拼长图、拼相框等图片编辑功能&#xff0c;另外还有一个简易的表情包制作功能。 主要有以下几个功能&#xff1a;图片裁剪、添加文字、涂鸦功能、拼长图、拼相框、表…

mybati缓存了解

title: “mybati缓存了解” createTime: 2021-12-08T12:19:5708:00 updateTime: 2021-12-08T12:19:5708:00 draft: false author: “ggball” tags: [“mybatis”] categories: [“java”] description: “mybati缓存了解” mybatis的缓存 首先来看下mybatis对缓存的规范&…

Ingress Controller

什么是 Ingress Controller &#xff1f; 在云原生生态中&#xff0c;通常来讲&#xff0c;入口控制器( Ingress Controller )是 Kubernetes 中的一个关键组件&#xff0c;用于管理入口资源对象。 Ingress 资源对象用于定义来自外网的 HTTP 和 HTTPS 规则&#xff0c;以控制进…

el-image 和 el-table冲突层级冲突问题

其中原理&#xff0c;很多博客已经所过了&#xff0c;table组件中使用图片&#xff0c;会出现层级过低问题&#xff0c; 网上大部分解决方式是 使用穿透 // 单元格样式 ::v-deep(.el-table__cell) {position: static !important; }我在此不推荐这种解决方式&#xff0c;原因&a…

Leetcode228. 汇总区间

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给定一个 无重复元素 的 有序 整数数组 nums 。 返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说&#xff0c;nums 的每个元素都恰好被某个区间范围所覆盖&#xff0c;并且不存在属…

二、VXLAN BGP EVPN基本原理

VXLAN BGP EVPN基本原理 1、BGP EVPN2、BGP EVPN路由2.1、Type2路由——MAC/IP路由2.2、Type3路由——Inclusive Multicast路由2.3、Type5路由——Inclusive Multicast路由 ————————————————————————————————————————————————…

聚焦云原生安全|如何为5G边缘云和工业互联网应用筑牢安全防线

9月22日&#xff0c;2023年中国信息通信业发展高层论坛5G工业互联网分论坛在北京顺利举办。 作为国内云原生安全领导厂商&#xff0c;安全狗受邀出席此次活动。 据悉&#xff0c;中国信息通信业发展高层论坛是致力于研究信息通信业发展新问题、新趋势&#xff0c;推动信息通信…

uniapp项目实践总结(二十三)网页和小程序应用打包教程

导语&#xff1a;当你的应用程序开发完成后&#xff0c;在发布到互联网之前&#xff0c;需要进行打包操作&#xff0c;包括网页端、小程序端的打包。 目录 准备工作网页打包小程序打包 准备工作 在打包之前&#xff0c;请保证你的 uniapp 应用程序编译到网页、小程序是可以正…

标准化、逻辑回归、随机梯度参数估计

机器学习入门 数据预处理&#xff1a; 将&#xff1f;替换为缺失值 data data.replace(to_replace"?",valuenp.nan)丢掉缺失值 data.dropna(how"any) #howall删除全是缺失值的行和列 #haowany删除有缺失值的行和列将数据集划分成测试集和训练集 data[colu…

tensor数学运算

运算函数加add减sub乘mul除div矩阵相乘matmul次方pow平方根及其倒数sqrt 和 rsqrt向下/向上取整floor / ceil分离出整数/小数trunc / frac近似解四舍五入round裁剪clamp 1、矩阵元素的加减乘除 注意是矩阵间对应位置元素进行加减乘除 add 和 a torch.rand(3,4) b torch.…

ceph分布式存储部署

一、概述 是一个统一的分布式存储系统&#xff0c;设计初衷是提供较好的性能、可靠性和可扩展性。 特点 1、统一存储 虽然 ceph 底层是一个分布式文件系统&#xff0c;但由于在上层开发了支持对象和块的接口。所以在开源存储软件中&#xff0c;能够一统江湖。至于能不能千秋万…

面试打底稿④ 专业技能的第四部分

简历原文 抽查部分 了解Python的使用&#xff08;第一篇关于Python升级版本bug解决的文章斩获6W阅读&#xff09;&#xff0c;用python实现了几篇图像信息隐藏领 域论文的复现&#xff08;博客中有提及&#xff09;&#xff1b; 了解Django基本框架&#xff0c;写过Django框架的…

【深度学习实验】卷积神经网络(二):自定义简单的二维卷积神经网络

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 二维互相关运算&#xff08;corr2d&#xff09; 2. 二维卷积层类&#xff08;Conv2D&#xff09; a. __init__&#xff08;初始化&#xff09; b. forward(前向传…

第十四届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组 试题 B: 双子数

[蓝桥杯 2023 国 B] 双子数 试题 B: 双子数 【问题描述】 若一个正整数 x x x 可以被表示为 p 2 q 2 p^2 \times q^2 p2q2&#xff0c;其中 p p p、 q q q 为质数且 p ≠ q p \neq q pq&#xff0c;则 x x x 是 一个 “双子数”。请计算区间 [ 2333 , 233333333333…

千兆光模块和万兆光模块的差别是什么?

千兆光模块和万兆光模块是目前使用最广泛的光模块之一&#xff0c;它们之间有什么差别呢&#xff1f;下面从传输速率、光纤类型、距离等多个方面详细分析千兆光模块和万兆光模块的差别。 一、传输速率 千兆光模块的传输速率为1.25Gbps&#xff0c;而万兆光模块的传输速率为10…

记录一下 malloc 是如何分配内存的

系统深入学习笔记-malloc 以 32 位系统为例&#xff0c;&#xff0c;通过这张图你可以看到&#xff0c;用户空间内存从低到高分别是 6 种不同的内存段&#xff1a; 代码段&#xff0c;包括二进制可执行代码&#xff1b;数据段&#xff0c;包括已初始化的静态常量和全局变量B…