Java 基础--- Object Class

2023-11-19

Object Class 结构

在这里插入图片描述

toString()

  • toString源码, 默认返回格式:对象的 class 名称 + @ + hashCode 的十六进制字符串
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
class RunoobTest {
    public static void main(String[] args) {
 
        // toString() with Object
        Object obj1 = new Object();
        System.out.println(obj1.toString());
 
        Object obj2 = new Object();
        System.out.println(obj2.toString());
 
        Object obj3 = new Object();
        System.out.println(obj3.toString());
    }
}

以上程序执行结果为:
java.lang.Object@d716361
java.lang.Object@6ff3c5b5
java.lang.Object@3764951d
  • 根据实际需求重写, 一般print类中所有属性的值

clone()

  • clone()方法是用于浅克隆或者深克隆一个java对象的
  • 但是要注意一个误区:clone方法是Object类的,并不是Cloneable接口的,Cloneable只是一个标记接口,标记接口是用于标记实现该接口的类具有某种该接口标记的功能,常见的标记接口有三个:Serializable、Cloneable、RandomAccess,没有实现Cloneable接口,那么调用clone方法就会爆出CloneNotSupportedException异常。
  • 要使得一个java类可以实现克隆,那么该类就需要实现Cloneable接口,并且重写基类Object的clone方法,其实Object的clone方法就已经默认有克隆的能力了,并且实现的是浅克隆,那为什么一定得重写clone方法呢?
  • 我们先来看Object类的clone方法源码:
protected native Object clone() throws CloneNotSupportedException;
  • 方法被native关键字修饰,并且该方法没有方法体,没有方法体的方法我们认为是抽象方法,可是Object类并不是一个抽象类,而是一个具体类,那为什么还能容纳抽象方法呢,其实就是native关键字在起作用,被native关键字修饰的方法属于本地方法,表示Java的作用范围已经无法达到,底层会去调用C语言或者C++的库。
  • 该方法是被protected修饰,这就表明我们在子类中不重写此方法,就在子类外无法访问,因为这个protected权限是仅仅能在Object所在的包和子类能访问的,这也验证了子类重写父类方法权限修饰符可以变大但不能变小的说法。
  • 所以我们要使得一个类具有clone的能力,可以先实现Cloneable接口,再重写clone方法,方法内部去调用了父类的clone方法,其实是为了扩大访问权限,也可以把protected改为public,以后再继承就不用重写了。当然这只是浅克隆的clone函数,深克隆就需要修改clone的方法体了。
public class Mytest implements  Cloneable{
    /**
     * 重写clone方法,调用父类默认的clone方法,实现的是浅克隆
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

————————————————
版权声明:本文为CSDN博主「can_chen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/can_chen/article/details/106816513

finalize()

  • Object finalize() 方法用于实例被垃圾回收器回收的时触发的操作。
  • 当 GC (垃圾回收器) 确定不存在对该对象的有更多引用时,对象的垃圾回收器就会调用这个方法。
import java.util.*;
 
class RunoobTest extends GregorianCalendar {
    public static void main(String[] args) {
        try {
            // 创建 RunoobTest 对象
            RunoobTest cal = new RunoobTest();
 
            // 输出当前时间
            System.out.println("" + cal.getTime());
 
            // finalize cal
            System.out.println("Finalizing...");
            cal.finalize();
            System.out.println("Finalized.");
 
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }
}

输出结果:
Sun Oct 11 11:36:46 CST 2020
Finalizing...
Finalized.

getClass()

  • Object getClass() 方法用于获取对象的运行时对象的类, 可以常在反射中用到
    import java.util.ArrayList;
class RunoobTest {
    public static void main(String[] args) {
 
    // getClass() with Object
    Object obj1 = new Object();
    System.out.println("obj1 的类为: " + obj1.getClass());
 
    // getClass() with String
    String obj2 = new String();
    System.out.println("obj2 的类为: " + obj2.getClass());
 
    // getClass() with ArrayList
    ArrayList<Integer> obj3 = new ArrayList<>();
    System.out.println("obj3 的类为: " + obj3.getClass());
    
    // 创建 RunoobTest 类的对象
    RunoobTest obj4 = new RunoobTest();
    System.out.println("obj3 的类为: " + obj4.getClass());
    }
}

以上程序执行结果为:
obj1 的类为: class java.lang.Object
obj2 的类为: class java.lang.String
obj3 的类为: class java.util.ArrayList
obj4 的类为: class RunoobTest
  • 在获得类型类之后,你就可以调用其中的一些方法获得类型的信息了,主要的方法有:
getName():String:获得该类型的全称名称。

getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回nullgetInterfaces():Class[]:获得该类型实现的所有接口。

isArray():boolean:判断该类型是否是数组。

isEnum():boolean:判断该类型是否是枚举类型。

isInterface():boolean:判断该类型是否是接口。

isPrimitive():boolean:判断该类型是否是基本类型,即是否是intbooleandouble等等。

isAssignableFrom(Class cls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。

getComponentType():Class:如果该类型是一个数组,那么返回该数组的组件类型。

equals(Object obj)

  • equals方法是 判断两个对象是否相等
  • equals源码
public boolean equals(Object obj) {
	return (this == obj);
}
  • 在Object类中的equals方法当中, 用“ ==”判断的是两个java对象的内存地址是否相等
  • 我们应该判断两个java对象的内容是否相等。所以需要子类重写equals。
  • 基本数据类型,判断相等用“==”
  • 引用数据类型,判断相等必须重写equals()方法,不然比较的是内存地址

hashCode()

什么是hashcode

public native int hashCode(); //native 关键字修饰的方法,用 C/C++ 语言实现
  • java根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为hashcode

hashcode的主要作用

  • 对于hashset, hashmap, hashtable等方法需要判断数据是否一样, 可以使用 equals() 方法进行逐个比较, 但是这种方如果数据量特别特别大,采用 equals() 方法进行逐个对比的效率肯定很低. 最好的解决方案就是哈希表.

关于重写equals必须重写hashcode方法

  • 每个覆盖了equals方法的类中,必须覆盖hashCode。如果不这么做,就违背了hashCode的通用约定,也就是上面注释中所说的。进而导致该类无法结合所以与散列的集合一起正常运作,这里指的是HashMap、HashSet、HashTable、ConcurrentHashMap。 — Effective Java 第三版

具体Example

  • 我们知道HashMap中的key是不能重复的,如果重复添加,后添加的会覆盖前面的内容。那么我们看看HashMap是如何来确定key的唯一性的。
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
  • 查看代码发现,它是通过计算Map key的hashCode值来确定在链表中的存储位置的。那么这样就可以推测出,如果我们重写了equals但是没重写hashCode,那么可能存在元素重复的矛盾情况
public class Employee {

private String name;

private Integer age;

public Employee(String name, Integer age) {
    this.name = name;
    this.age = age;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Employee employee = (Employee) o;
    return Objects.equals(name, employee.name) &&
            Objects.equals(age, employee.age);
}
public static void main(String[] args) {

    Employee employee1 = new Employee("冰峰", 20);
    Employee employee2 = new Employee("冰峰", 22);
    Employee employee3 = new Employee("冰峰", 20);

    HashMap<Employee, Object> map = new HashMap<>();

    map.put(employee1, "1");
    map.put(employee2, "1");
    map.put(employee3, "1");

    System.out.println("equals:" + employee1.equals(employee3));
    System.out.println("hashCode:" + (employee1.hashCode() == employee3.hashCode()));
    System.out.println(JSONObject.toJSONString(map));
}
  • 按正常情况来推测,map中值存在两个元素,employee2和employee3, 因为employee1和employee3一样(equal被重写了) 会被覆盖
  • 实际执行结果
    在这里插入图片描述
  • 出现这种问题的原因就是因为没有重写hashCode,导致map在计算key的hash值的时候,绝对值相同的对象计算除了不一致的hash值。
@Override
public int hashCode() {
    return Objects.hash(name, age);
}
}
  • 加入重写hashcode, 根据name和age产生hash值
  • 运行结果
    在这里插入图片描述

关于利用hashcode和equals比较两个object

  • 先对比两个object的hashcode
  • 如果hahcode不一样则一定不一样
  • 如果两个object的hashcode一致, 则说明有可能一样(因为存在hash冲突)
  • 所以还需要调用equals进行实际比较

wait() and notify() — to be continued

Object wait() 方法让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。

当前线程必须是此对象的监视器所有者,否则还是会发生 IllegalMonitorStateException 异常。

如果当前线程在等待之前或在等待时被任何线程中断,则会抛出 InterruptedException 异常。

notifyAll()

wait(long timeout)

wait(long timeout, int nanos)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 基础--- Object Class 的相关文章

  • 如何在 Spring Data 中选择不同的结果

    我在使用简单的 Spring Data 查询或 Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题 如何选择三列 研究 国家 登录 不同的行 并且查询结果将是用户对象类型的列表 Table User Id S
  • 在 mvn 命令中指定 pom.xml 并混合其他项目的目标

    我有多个问题 我可以在 mvn 命令中指定 pom xml 吗 在当前项目上执行 mvn 命令时 我可以混合另一个项目的目标吗 例如 mvn clean otherproject comple otherproject install ot
  • 如何将 javax.persistence.Column 定义为 Unsigned TINYINT?

    我正在基于 MySQL 数据库中的现有表创建 Java 持久性实体 Bean 使用 NetBeans IDE 8 0 1 我在这个表中遇到了一个字段 其类型为 无符号 TINYINT 3 我发现可以执行以下操作将列的类型定义为 unsign
  • @RestController 没有 @ResponseBody 方法工作不正确

    我有以下控制器 RestController RequestMapping value base url public class MyController RequestMapping value child url method Req
  • JVisualVM/JConsole 中的 System.gc() 与 GC 按钮

    我目前正在测试处理 XML 模式的概念验证原型 并围绕一个非常消耗内存的树自动机外部库 我已经获得了源代码 构建 我想绘制 真实峰值 堆 随着模式大小的增加 不同运行的内存消耗 使用的指标符合我的目的并且不会影响问题 或者至少是它的合理近似
  • 使用 GWT 读取非常大的本地 XML 文件

    我正在使用 GWT 构建我的第一个 Java 应用程序 它必须从一个非常大的 XML 文件中读取数据 当我尝试发送对文件中信息的请求时遇到问题 并且我不太确定它是否与文件的大小或我的语义有关 在我的程序中 我有以下内容 static fin
  • 在 Wildfly 中与 war 部署共享 util jar 文件

    假设我有一个名为 util jar 的 jar 文件 该 jar 文件主要包含 JPA 实体和一些 util 类 无 EJB 如何使这个 jar 可用于 Wildfly 中部署的所有 war 无需将 jar 放置在 war 的 WEB IN
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • Kotlin 未解决的参考:CLI 上 gradle 的 println

    放一个printlnkotlin 函数返回之前的语句会崩溃 堆栈跟踪 thufir dur NetBeansProjects kotlin thufir dur NetBeansProjects kotlin gradle clean bu
  • 自动生成Flyway的迁移SQL

    当通过 Java 代码添加新模型 字段等时 JPA Hibernate 的自动模式生成是否可以生成新的 Flyway 迁移 捕获自动生成的 SQL 并将其直接保存到新的 Flyway 迁移中 以供审查 编辑 提交到项目存储库 这将很有用 预
  • 是否可以通过编程方式查找 logback 日志文件?

    自动附加日志文件以支持电子邮件会很有用 我可以以编程方式设置路径 如以编程方式设置 Logback Appender 路径 https stackoverflow com questions 3803184 setting logback
  • 如何使用 Hibernate (EntityManager) 或 JPA 调用 Oracle 函数或过程

    我有一个返回 sys refcursor 的 Oracle 函数 当我使用 Hibernate 调用该函数时 出现以下异常 Hibernate call my function org hibernate exception Generic
  • 生成的序列以 1 开头,而不是注释中设置的 1000

    我想请求一些有关 Hibernate 创建的数据库序列的帮助 我有这个注释 下面的代码 在我的实体类中 以便为合作伙伴表提供单独的序列 我希望序列以 1000 开头 因为我在部署期间使用 import sql 将测试数据插入数据库 并且我希
  • Java Swing For mac 中的 DJ Native Swing 浏览器

    我有一个用 Swing 制作的 Java 应用程序 并且使用了一个 DJ Native Swing 浏览器 当我尝试在 OS X 上使用它时 它抛出了一个NoClassDefFoundError尽管我添加了 swt jar 但始终如此 有人
  • 了解joda时间PeriodFormatter

    我以为我明白了 但显然我不明白 你能帮我通过这些单元测试吗 Test public void second assertEquals 00 00 01 OurDateTimeFormatter format 1000 Test public
  • 使用布尔值进行冒泡排序以确定数组是否已排序

    我有以下用于冒泡排序的代码 但它根本不排序 如果我删除布尔值那么它工作正常 我知道 由于我的 a 0 小于所有其他元素 因此没有执行交换 任何人都可以帮助我解决这个问题 package com sample public class Bub
  • 是否可以使用 Java Guava 将函数应用于集合?

    我想使用 Guava 将函数应用于集合 地图等 基本上 我需要调整 a 的行和列的大小Table分别使所有行和列的大小相同 执行如下操作 Table
  • 将 Apache Camel 执行器指标发送到 Prometheus

    我正在尝试转发 添加 Actuator Camel 指标 actuator camelroutes 将交换 交易数量等指标 发送到 Prometheus Actuator 端点 有没有办法让我配置 Camel 将这些指标添加到 Promet
  • 泛型、数组和 ClassCastException

    我想这里一定发生了一些我不知道的微妙事情 考虑以下 public class Foo
  • 在浏览器刷新中刷新检票面板

    我正在开发一个付费角色系统 一旦用户刷新浏览器 我就需要刷新该页面中可用的统计信息 统计信息应该从数据库中获取并显示 但现在它不能正常工作 因为在页面刷新中 java代码不会被调用 而是使用以前的数据加载缓存的页面 我尝试添加以下代码来修复

随机推荐

  • 5种常见函数的写法和调用方式

    前言 函数在开发中随处可见 经常在开发中我们声明函数就使用了一两种就已经足够了 但是 对我这有梦想的码农来说 这显然是不够的 因此 总结整理了5中常见的声明方式和调用方式 1 函数声明 最常规写法 常规函数写法 function bar c
  • Request processing failed;nested exception is java.lang.*

    目录 问题 分析 解决 附录 注意 参考 问题 错误1 httpClient向服务端发送请求 服务端有时候就会给客户端返回 500错误 打开服务端错误日志 报如下错误 2021 05 28 21 05 06 548 default http
  • 面试官让我讲讲分布式系统容错架构,结果。。。

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 目录 TB级数据放在一台机器上 难啊 到底啥是分布式存储 啥又是分布式存储系统 某台机器宕机了咋办 Master节点如何感知到数据副本消失 如何复制副本保持足够副本数
  • 遥感新赛事!变化检测、图像融合等比赛全面启动!2023"国丰东方慧眼杯"遥感影像智能处理算法大赛来了!...

    点击下方卡片 关注 CVer 公众号 AI CV重磅干货 第一时间送达 2023 国丰东方慧眼杯 遥感影像智能处理算法大赛火热进行中 遥感影像智能处理算法大赛是国家自然科学基金委信息科学部 空间信息网络基础理论与关键技术 重大研究计划指导专
  • 剑指 Offer 14- I. 剪绳子(343. 整数拆分)&& 剑指 Offer 14- II. 剪绳子 II —思路和心得

    剑指 Offer 14 I 剪绳子 和剪绳子1相同的题 思路 利用动态规划 因为每个长度大于3的绳子的最大值都可以划分为2和3的乘积 我们想将长度为 2 3的绳子的最大值先算出来 然后再利用动态规划 进步算出长度为n的绳子的最大值 clas
  • 国内比较好的软件接单平台有哪些?

    随着企业信息化水平的提高 已经有很多企业意识到了使用专用软件可以大大提高资金使用率 提高员工的工作效率 降低成本 同现有业务接轨 即软件设计思路和方法的一般过程 包括设计软件的功能和实现的算法和方法 软件的总体结构设计和模块设计 编程和调试
  • git安装配置

    安装 当前ubuntu镜像中已经安装好了git 以下步骤可以跳过 安装 sudo apt get install git 安装成功后 运行如下命令 git 配置 在ubuntu的命令行中 修改某台机器的git配置 修改为注册github时的
  • sentinel3数据批量下载——sentinelsat

    本文主要记录利用sentinelsat包批量下载sentinel2数据 转载 https blog csdn net mrzhy1 article details 107044828 方法一 直接利用sentinelsat包 1 senti
  • 什么是单向数据流

    当父组件给子组件传递数据的时候 子组件只允许进行数据的读操作 不允许做数据的改操作 因为当子组件改变父组件传递过来的数据的话会造成数据流难以理解 简单分析一下 当子组件中更改了父级的内容时 其他需要引用父级组件也会被更改 从而导致父级组件在
  • python怎么算积分_python计算积分

    python有多个方法计算积分 下面介绍其中三个 以下式为例 方法一 直接用numpy计算 start 1 stop 2 length 101 x np linspace start stop length y x 2 result sum
  • Kotlin+Compose+MVVM模式(井字棋)

    井字棋 简单的演示一下MVVM模式结合Compose的运用 Compose 组合 1 Model 2 View activity fragment composable 3 ViewModel livedata gt stateOf 声明式
  • Qt框架及模块认识

    小白自工作就接触Qt 一直都在使用Qt5 3 1版本 所以没有经历过大牛们把项目从Qt4程序到Qt5的烦恼 没准以后会碰到 对Qt所有的丰富的API表示惊叹 对于Qt的框架及模块认识也是极为模糊的 文中有不对之处希望大牛们打脸 虽然脸都已经
  • AFX_MANAGE_STATE(AfxGetStaticModuleState())的使用

    MSDN By default MFC uses the resource handle of the main application to load the resource template If you have an export
  • jsp上显示JFreeChart生成的饼状图

    文件配置
  • UE4(Unreal Engine4)在蒙太奇动画中添加音频轨道通知

    UE4系列文章目录 文章目录 UE4系列文章目录 前言 一 遇到的问题 二 操作步骤 前言 UE4 Unreal Engine4 在蒙太奇动画中添加音频轨道通知 我们想在某一帧动画中添加声音 比如我们想在动画的第13帧这里添加音效 一 遇到
  • 对于单向链表的排序与去重

    include bits stdc h using namespace std struct node int num node next class Chain public Chain head tail new node void G
  • 【计算机科学】【2017】变分推理与深度学习

    本文为荷兰阿姆斯特丹大学 作者 Kingma D P 的博士论文 共174页 在本文中 我们提出了变分 贝叶斯 推理 生成建模 表示学习 半监督学习和随机优化问题的新的解决方案 我们提出了一种有效的变分推理算法 Kingmaand Well
  • 解析目标检测全流程!附代码数据

    关注后 星标 Datawhale 每日干货 每月组队学习 不错过 Datawhale干货 作者 王程伟 算法工程师 Datawhale成员 在计算机视觉中 红外弱小目标检测是一个重要的方向 但直到近一两年 才开始运用一些深度学习的方法 深度
  • 二叉树的递归遍历、非递归遍历、层次遍历

    1 递归遍历 2 非递归遍历 3 层次遍历 1 递归遍历 在使用递归遍历的时候 每个节点会经过三次 public class PreInPosTraversal public static class Node public int val
  • Java 基础--- Object Class

    Java 基础 Object Class Object Class 结构 toString clone finalize getClass equals Object obj hashCode 什么是hashcode hashcode的主要