Java基础-面向对象总结(1)

news2025/1/24 17:54:50

本文主要梳理关于 Java面向对象的基础知识,希望对你有帮助

 

  • Java对象

目录

Java对象

Java创建对象有几种方式

创建一个对象用什么运算符? 对象实体与对象引用有何不同?

创建一个对象的步骤

Java对象都包含什么 ? 

new Object()对象占多少个字节?

对象的比较

对象的相等和引用相等的区别

==和 equals 的区别?

String类的equals方法源码有了解么 ? 

Comparator与Comparable有什么区别?

不可变对象


Java对象

Java创建对象有几种方式

创建对象总共有5种方式

  • 通过 new 关键字创建对象
//1.通过new关键字创建对象
Student s1 = new Student();
  • 通过 Class 类的 newInstance() 方法
//2.通过类.class的newInstance方法
Student s2 = Student.class.newInstance();

通过 Constructor 类的 newInstance 方法

//3.通过类构造方法的newInstance方法
Constructor<Student> constructor = Student.class.getConstructor();
Student s3 = constructor.newInstance();

利用 Clone 方法

//4.利用 Clone 方法-->实现cloneable接口并且重写clone方法
Student s4 = new Student();
try {
     Student s5 = (Student) s4.clone();
} catch (CloneNotSupportedException e) {
     e.printStackTrace();
}

反序列化

//5.通过序列化保存,反序列化创建对象 --> 记得要实现序列化接口
Student s6 = new Student();
try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:\\data.txt"))) {
    objectOutputStream.writeObject(s6);
}catch (IOException e) {
    e.printStackTrace();
}
//反序列化创建对象
try(ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:\\data.txt"))) {
    Student s7 = (Student) objectInputStream.readObject();
    System.out.println(s7);
} catch (Exception e) {
    e.printStackTrace();
}

创建一个对象用什么运算符? 对象实体与对象引用有何不同?

创建一个对象使用new关键字,对象实体是真正创建出来的对象(对象实体存放在堆内存),对象引用存放的是对象的地址(对象引用存放在栈内存中),对象引用指向对象.

  • 一个引用只可以指向1个对象或者0个对象.
  • 一个对象可以被多个引用所指向.

创建一个对象的步骤

  • 为对象分配内存空间
  • 初始化该对象
  • 给对象的引用赋值

Java对象都包含什么 ? 

首先 , 对象的组成有3个部分:对象头,实例数据,对齐填充字节, 对象头又包括 markword,指向class的指针,数组长度(如果不是数组的话就没有)

  1. 对象头
  • markword

如果jvm是32位,则Mark Word是32bit;如果64位,则Mark Word是64bit。Mark Word结构如下:

在这里插入图片描述

 Mark Workd存储的是对象自身运行时的数据,比如:锁标志位;是否偏向锁;GC分代年龄;对象的hashCode;获取到该锁的线程的线程ID;偏向时间戳(Epoch)等等。

  • Klass Word 类型指针

如果jvm是32bit,则Klass Word是32bit;如果jvm是64bit,则Klass Word是64bit。
Java对象存放在堆中,但其类信息存放在方法区中,所以Klass word指向该对象的类信息。

JVM通过这个指针来确定该对象是哪个类的实例

  • 数组长度
如果对 象是一个Java 数组,那在对象头中还必须有一块用于记录数组长度的数据

如果jvm是32bit,则数组长度是32bit;如果jvm是64bit,则数组长度是64bit

    2. 实例数据

来实例数据部分是对象真正存储的有效信息,即我们在程序代码里面所定义的各种类型的字
段内容,无论是从父类继承下来的,还是在子类中定义的字段都必须记录起来

    3. 对其填充字节

jvm要求Java对象占用内存的大小是8byte的倍数,因此需要把对象的大小补齐至8byte倍数。

另外 , 32位系统和64位系统不同区域占用空间大小的区别,因为在64位平台的HotSpot中使用32位指针(实际存储用64位),内存使用会多出1.5倍左右,使用较大指针在主内存和缓存之间移动数据,占用较大宽带,同时GC也会承受较大压力

但是现在假设一个场景,公司现在项目部署的机器是32位的,你们老板要让你将项目迁移到64位的系统上,但是又因为64位系统比32位系统要多出更多占用空间,怎么办,因为正常来说我们是不需要这一部分多余空间的,所以jvm已经帮你考虑好了,那就是指针压缩。

指针压缩

-XX:+UseCompressedOops 这个参数就是JVM提供给你的解决方案,可以压缩指针,将占用的空间压缩为原来的一半,起到节约空间的作用,classpointer参数大小就受到其影响。


new Object()对象占多少个字节?

64位系统下 :

  • 在开启指针压缩的情况下,markword占用8字节,classpoint占用4字节,Interface data无数据,总共是12字节,由于对象需要为8的整数倍,Padding会补充4个字节,总共占用16字节的存储空间。
  • 在没有指针压缩的情况下,markword占用8字节,classpoint占用8字节,Interface data无数据,总共是16字节。

对象的比较

对象的相等和引用相等的区别

对象相等指的是内存中存放的内容是否相等.

引用相等是指它们指向的内容地址是否相等.

==和 equals 的区别?

先说说 ==  ,对于==来说比较基本数据类型和引用数据类型有不同

  • 基本数据类型 : 比较的是
  • 引用类型 : 比较的是对象的内存地址

根本原因就是 Java都是值传递,不管是基本数据类型还是引用数据类型都比较的都是值,基本数据类型的值就是值,而引用数据类型是内存地址

再说说equals方法 ,equals方法只能用于判断两个对象是否相等,不能用来判断基本数据类型,另外equals方法来源于Object类,又因为Object类是所有类的父类,所以,所有类都有equals方法,如果没有重写,默认就是Object类的equals方法.

//默认的equals方法
public boolean equals(java.lang.Object obj) {
    return (this==obj);//【这里比对的是对象的内存地址】
}

对于equals有两种情况 :

  • 没有重写equals方法, 与==一样,默认是Object的equals方法
  • 重写了equals方法, 比较的对象的内容,相等返回true

String类的equals方法源码有了解么 ? 

对于String类就重写了equals方法,所以我们一般比较字符串的时候,比较的是两个字符串的内容

public boolean equals(Object anObject) {
    if (this == anObject) {//先比较两个字符串的内存地址是否相同
        return true;//相同返回true
    }
    if (anObject instanceof String) {//看该字符串是否是String类型
        String anotherString = (String) anObject;
        int n = value.length;
        if (n == anotherString.value.length) {//如果字符串长度相等,转化成字符数组,一一比较字符
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                //发现字符不相同,直接返回false
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    //长度不同直接返回false
    return false;
}

Comparator与Comparable有什么区别?

Comparable 和 Comparator 都是用来实现元素排序的,它们二者的区别如下:

  • Comparable 是“比较”的意思,而 Comparator 是“比较器”的意思;
  • Comparable 是通过重写 compareTo 方法实现排序的,而 Comparator 是通过重写 compare 方法实现排序的;
  • Comparable 必须由自定义类内部实现排序方法,而 Comparator 是外部定义并实现排序的。

总结二者的区别:Comparable 可以看作是“对内”进行排序接口,而 通过 Comparator 接口可以实现和原有类的解耦,在不修改原有类的情况下实现排序功能,所以 Comparator 可以看作是“对外”提供排序的接口。

@Data
public class Person implements Comparable<Person> {
    private int id;
    private int age;
    private String name;

    public Person(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    /**
     * 重写 compareTo 方法来实现自定义排序规则
     * compareTo 方法接收的参数 p 是要对比的对象,排序规则是用当前对象和要对比的对象进行比较,
     * 然后返回一个 int 类型的值。正序从小到大的排序规则是:使用当前的对象值减去要对比对象的值;
     * 而倒序从大到小的排序规则刚好相反:是用对比对象的值减去当前对象的值。
     * @param p
     * @return
     */
    @Override
    public int compareTo(Person p) {
        return p.getAge() - this.getAge();
    }
}
@Data
public class Person2 {
    private int id;
    private int age;
    private String name;

    public Person2(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }
}
//实现一个比较器 --> “对外”提供排序的接口。
class PersonComparator implements java.util.Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}

不可变对象

怎么实现一个不可变对象

如果要实现 immutable 的类,我们需要做到:

  1. 将class自身声明为final,这个类就不能被继承(别人就不能扩展来绕过限制)
  2. 将所有成员变量定义为 private 和final,并且不要实现setter方法
  3. 如果要修改类的状态,必须返回一个新的对象。
  4. 通常构造对象的时候,成员变量使用深拷贝来初始化,而不是直接赋值,(无法确定输入对象不被其他人修改) 
  5. 如果确实需要实现getter方法,或者其他可能返回内部状态的方法,使用 copy-on-write原则,创建私有的copy.
  6. 对于getter方法,和setter方法,建议做还是确定有需要的时候再去实现

不可变的好处是什么 ? 

对于String来说

  • 安全性

String 是 Java 中最基础也是最长使用的类,经常用于存储一些敏感信息,例如用户名、密码、网络连接等。因此,String 类的安全性对于整个应用程序至关重要。字符串容易被修改

  • 节省空间——字符串常量池

通过引入字符串常量池来节省空间,内容相同的字符串可以使用相同的字符串,可以节省内存空间,如果String可以改变,并且这个对象被其他多个地方所引用,这个字符串被修改,所有的地方都会被修改

  • 线程安全

String 对象是不可修改的,如果线程尝试修改 String 对象,会创建新的 String,所以不存在并发修改同一个对象的问题。

  • 性能

String 被广泛应用于 HashMap、HashSet 等哈希类中,当对这些哈希类进行操作时,例如 HashMap 的 get/put,hashCode 会被频繁调用。

由于不可变性,String 的 hashCode 只需要计算1次后就可以缓存起来,因此在哈希类中使用 String 对象可以提升性能。


能否创建一个包含可变对象的不可变对象

不要共享可变对象的引用就可以了,如果需要变化时,就返回原对象的一个拷贝

参考 :

String 为什么不可变?不可变有什么好处?_string为什么不可变_程序员囧辉的博客-CSDN博客

能否创建一个包含可变对象的不可变对象?_秋风清,秋月明。落日夕阳一片红的博客-CSDN博客

元素排序Comparable和Comparator有什么区别? - 掘金

Java基础常见面试题总结(中) | JavaGuide(Java面试 + 学习指南)

聊聊Java中的不可变对象 | Java程序员进阶之路

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

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

相关文章

kafka原理之生产者

batch.size:只有数据累计到batch.size后&#xff0c;sender才会发送数据。默认16k linger.ms:如果迟迟没有达到batch.size&#xff0c;sender等待linger.ms设置时间之后&#xff0c;发送数据。单位:ms,默认0(没有延迟) acks设置: 0:不需要等待数据落盘应答&#xff1b;1:leader…

Java ---多线程(下)

&#xff08;一&#xff09;目录 线程的优先级 守护线程 线程同步 线程并发协作 主要内容 &#xff08;二&#xff09;线程的优先级 1 什么是线程的优先级 每一个线程都是有优先级的&#xff0c;我们可以为每个线程定义线程的优先级&#xff0c;但是这并不能保 证高优…

Anaconda下载与安装详解

文章目录 1 Anaconda1.1 简介1.2 下载安装1.3 配置环境变量1.4 下载配置1.4.1 conda配置1.4.1.1 修改conda下载源1.4.1.2 删除下载源1.4.1.3 包下载目录1.4.1.4 下载报错 1.4.2 pip配置1.4.2.1 配置源1.4.2.2 下载目录1.4.2.3 修改下载目录 1.5 修改虚拟环境地址1.5.1 通过配置…

【软件开发】Memcached(理论篇)

Memcached&#xff08;理论篇&#xff09; 1.Memcached 简介 Memcached 是一个开源的&#xff0c;支持高性能&#xff0c;高并发的分布式内存缓存系统&#xff0c;由 C 语言编写&#xff0c;总共 2000 多行代码。从软件名称上看&#xff0c;前 3 个字符 Mem 就是内存的意思&am…

quartz原理

1.如何实现任务 2.3个组件 3.工作原理 在Quartz中&#xff0c;有两类线程&#xff0c;Scheduler调度线程和任务执行线程&#xff0c;其中任务执行线程通常使用一个线程池维护一组线程。 Scheduler调度线程主要有两个&#xff1a;执行常规调度的线程&#xff0c;和执行misfir…

【C++】关联式容器——mapset的使用

文章目录 1.关联式容器和键值对1. 关联式容器2. 键值对 2. 树形结构的关联式容器——set1. 模版参数列表2. 默认成员函数3. 迭代器4.容量相关操作5.modify6.其他操作接口 3. 树形结构的关联式容器——map1. 默认成员函数2. 迭代器3. 容量与数据访问4.数据修改5. 其他操作接口 1…

vue-5:router

router路由配置&#xff0c;使用 在vue-cli构建的vue单页面应用中&#xff0c;需要借助vue-router库实现路由功能 配置路由 (构建项目时要下载) router文件夹下创建&#xff1a;index.js&#xff0c;routerConfig.js配置路由 路由懒加载&#xff1a; 按需加载&#xff1a;…

轻松掌握线程基础知识和四种创建方式及区别

1、线程与进程 2、并行与并发 3、创建线程 1、方式一&#xff1a;继承Thread类 2、方式二&#xff1a;实现Runnable接口 3、方式三&#xff1a;实现Callable接口 4、方式四&#xff1a;线程池创建线程&#xff08;项目中使用的方式&#xff09; 5、Runnable和Callable区别 6、…

在 Windows 10/11、7/8 上清空后从回收站恢复已删除文件的 6 种方法

Windows&#xff08;包括 Windows 11、10、8、7 和 Vista&#xff09;上的回收站用于回收您打算删除的不需要的文件。如果您删除了一些重要的文件或文件夹并且不小心清空了回收站&#xff0c;您仍然有机会恢复从回收站中删除的文件。这是一个教程&#xff0c;将阐明“如何在清空…

HTML第一天

HTML第一天 我们接下来是进行的网页开发网页的相关概念: 什么是网页?什么是HTML?网页的形成? 什么是网页&#xff1a; 1.网站是指在因特网上根据一定的规则&#xff0c;使用 HTML 等制作的用于展示特定内容相关的网页集合。 2.网页是网站中的一“页”&#xff0c;通常是…

钓鱼圈子钓点钓场鱼漂钓位小程序开发

钓鱼圈子钓点钓场鱼漂钓位小程序开发 功能: 关注好友功能。一键导航至钓鱼点。学习交流。鱼票功能是本系统的—大亮点&#xff0c;此功能可应用于鱼场举办活动比赛以及日常预定位置&#xff0c;在小程序进行预定&#xff0c;线下核销。系统拥有商城功能&#xff0c;可以为运营…

深度学习环境配置系列文章(三):配置VS Code和Jupyter的Python环境

深度学习环境配置系列文章目录 第一章 专业名称和配置方案介绍 第二章 Anaconda配置Python和PyTorch 第三章 配置VS Code和Jupyter的Python环境 第四章 配置Windows11和Linux双系统 第五章 配置Docker深度学习开发环境 第三章文章目录 深度学习环境配置系列文章目录前言一、VS…

C语言中链表经典面试题目——复制带随机指针的链表

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;数据结构​​​​​​​ &#x1f525;座右铭&#xff1a;“不…

计算机数据表示和数据转换

1、计算机数据表示和数据转换 送入计算机的数字、字母和符号等信息必须转换成0、1组合的二进制形式形式才能被计算机所接收、存储和运算。能够进行计算的数据并且能得出一个明确的数值叫数值数据&#xff0c;其余信息是非数值数据。 1.1 数值数据的表示 数值数据的计数方式是进…

SpringBoot的自动装配

前言 众所周知&#xff0c;SpringBoot的自动装配是其核心功能之一&#xff0c;SpringBoot提供了许多自动配置类&#xff0c;我们通常会有这样的一个概念&#xff1a;“当应用程序启动时&#xff0c;SpringBoot会扫描路径上的自动配置类进行加载&#xff0c;从而大大简化了项目…

小白量化《穿云箭集群量化》(6)巡航导弹策略

小白量化《穿云箭集群量化》&#xff08;6&#xff09;响尾蛇导弹 响尾蛇导弹是非常著名的武器装备&#xff0c;响尾蛇导弹发射者只需雷达瞄准和发射动作&#xff0c;发射动作完成尽快脱离战场保全自身安全。响尾蛇导弹会自动追踪敌机&#xff0c;直至击毁敌机。 证券交易犹如…

MySQL基础(三十一)数据库其它调优策略

1 数据库调优的措施 1.1 调优的目标 尽可能 节省系统资源 &#xff0c;以便系统可以提供更大负荷的服务。&#xff08;吞吐量更大&#xff09;合理的结构设计和参数调整&#xff0c;以提高用户操作 响应的速度 。&#xff08;响应速度更快&#xff09;减少系统的瓶颈&#xf…

day37_jdbc

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 零、 复习昨日 见晨考 一、作业 package com.qf.homework;import com.qf.model.User;import java.sql.Connection; import java.sql.DriverManager; impo…

【笔试强训】(红与黑,五子棋,走迷宫)DFS+BFS算法解析

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: 笔试强训专栏 深度优先遍历&#xff08;Depth First Search, 简称 DFS&#xff09; 与广度优先遍历&#xff08;Breath First Search&#xff09;是图论中两种非常重要的算法。 本文就以习题的方式来给…

STM32F10X--EXTI--外部中断/事件控制器

一、EXTI是什么&#xff1f; EXTI&#xff08;External interrupt/event controller&#xff09;—外部中断/事件控制器&#xff0c;管理了控制器的20 个中断/事 件线。每个中断/事件线都对应有一个边沿检测器&#xff0c;可以实现输入信号的上升沿检测和下降沿的 检测。EXTI 可…