Java面向对象进阶5——包和final(含源码阅读)

简介: 包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术,不同的技术类放在不同的包下,方便管理和维护

一、前言


从本文开始,将会讲述Java面向对象中的一些小知识点,本文主要是讲述有关包和final的知识


二、包


1️⃣定义


包在操作系统中其实就是一个文件夹。包是用来分门别类的管理技术,不同的技术类放在不同的包下,方便管理和维护


2️⃣命名


  • 包名一般是公司域名倒写 + 包的作用
  • 全部英语小写
  • 路径名.路径名.xxx.xxx
  • 包名要用 “.” 连接
  • 包名的每个路径名必须是一个合法的标识符,而且不能是Java的关键字


3️⃣使用其他类


🟡使用同一个包中的类时,不需要导包

b4eb4aed7d0f463c85792fe65cd73fea.png

由于Test类和Teacher类同在一个polymorphism包中,使用在调用Teacher类时并不会报错,也不需要导包


🟡使用java.lang包中类时,不需要导包


37576bd0d80347bda39c507a40da26d6.png


当我们选中String后再使用 Ctrl+B 跟进,查看源码,发现String类是在 java.lang 包下


acd22e07b37c42849bcd6523299229e0.png


🟡如果同时使用两个包中同类名,需要用全类名


当不同的包中有相同的类名时,我们需要看清楚要调用的类名是在哪个包中的,并且在导入别的包中的类名时,需要用全类名


99a42a3a6f754fd1b3973821d43c19af.png

1ee121ddb7774e0493b52892efb19982.png


final关键字


1️⃣定义


不可改变,最终的含义,可以用于修饰类、方法和变量。

类:被修饰的类,不能被继承

方法:被修饰的方法,不能被重写

变量:被修饰的变量,有且仅能被赋值一次(常量)


2️⃣final修饰类


被修饰的方法,不能被继承


🟡代码测试


final class  Fu{
        public  void  show(){
            System.out.println("这是父类");
        }
    }
    class Zi extends Fu {
        @Override
        public void show(){
            System.out.println("这是子类");
        }
    }


上述代码在IDEA中会爆红


4ba2d90ea07d4038a5aab3f1487be8c1.png


🟡源码阅读


选中String类后使用 Ctrl+B 跟进,查看源码


76ede7851e614473927d18af9d05402f.png


此处的String类是被final修饰的,即不可被继承,所以String类不能被任何一个类当作是父类


3️⃣final修饰方法


被修饰的方法,不能被重写

🟡代码测试


class  Fu{
        public final void  show(){
            System.out.println("这是父类");
        }
    }
    class Zi extends Fu {
        @Override
        public void show(){
            System.out.println("这是子类");
        }
    }


上述代码在IDEA中会爆红,所以在编写代码时一定要注意该问题


c5ccc81135c14a2eaead24071fbb88e1.png


🟡源码阅读


Ctrl+N 查看类,搜索object类,并选择Java.lang


b85148f4d70a495b8f530f1f63e808c0.png

99866f1fd3784f24a533a07a0ebcde3b.png


native


这个方法体是调用本地其他语言(C语言、汇编语言等)来写的,在这里是看不到它的方法体


get class()


获取编译以后的字节码文件


方法的作用


获取到字节码文件的对象,并与本地的操作系统产生交互


可以看到这个类是被final类修饰的,即该方法不可改变


如果再往下阅读源码,会发现还有public final native void notify() 、public final native void notifyAll() 和 public final native void wait(long timeout) throws InterruptedException 三个被final修饰的方法,同样是不想让方法被改变


4️⃣final修饰基本数据类型


被修饰的变量,有且仅能被赋值一次(变为常量)


🟡代码实现


public static void main(String[] args) {
        final int a = 20;
        a = 30;
        System.out.println(a);
    }


此时代码会爆红


e32bd52f32ef4454b2a5ad11ceccf175.png


🟡源码阅读


Ctrl+N 查看类,搜索Math


70f3acc1441d4d3596345df4aeedbc60.png

dffd79c9067841a3a73c8e5ff370e591.png


可以看到,在Math类里面定义了两个常量 PIE


🟡常量


在实际开发中,常量一般作为系统的配置信息,方便维护,提高可读性


命名规范


单个单词:全部大写

多个单词:全部大写,单词间用下划线展开


5️⃣ final修饰引用数据类型


变量存储地址值不变,对象内部属性值可改变


🟡代码实现


public static void main(String[] args) {
        final int[] arr = {1,2,3,4,5};
        arr[0] = 0;
        arr[1] = 10;
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
    }


输出结果:0 10 3 4 5


6ea94e99b2f545319c9c7f73de656b78.png


上述代码改变的就是对象内部属性值,所以是可行的,但是如果我们改变一下存储地址值(类型改变)的话会怎么样


public static void main(String[] args) {
        final int[] arr = {1,2,3,4,5};
        arr = new int[20];
        arr[0] = 0;
        arr[1] = 10;
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }

791f4a8942204d36b6d8668436cf51a3.png


代码报错,原因是这样会改变其地址值


🟡源码阅读


Ctrl+N 查看类,搜索String类,并选择 Java.long


11c7c38cda504be2bc495ca90d481148.png

3c2cdb2c7fcc4c0ebf121021174d3940.png


可以看到底层是有一个数组来存储字符串的内容,因为是用final来修饰的数组,所以其地址值不能改变

byte

存储数据类型

value[]

用来存储字符串的数组

private

私有,即外界无法获取到 value 记录的地址值


我们可以在这个源码中通过 Ctrl+F12 来搜索一下,发现没有value的get和set方法,使得我们没办法从外界获取其记录的地址值


47c90e20a2dd47ea9afd3217c956f66f.png


总结一下,上面这些都是字符串无法改变的原因


四、结语


通过阅读源码,我们可以更加深刻的了解到其原理所在,在之后的文章中,我也会多加分析源码,尽可能的将原理讲清楚,如果有任何疑问以及不足之处,欢迎指正

相关文章
|
11天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
45 7
|
23天前
|
数据采集 人工智能 Java
Java产科专科电子病历系统源码
产科专科电子病历系统,全结构化设计,实现产科专科电子病历与院内HIS、LIS、PACS信息系统、区域妇幼信息平台的三级互联互通,系统由门诊系统、住院系统、数据统计模块三部分组成,它管理了孕妇从怀孕开始到生产结束42天一系列医院保健服务信息。
28 4
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
3天前
|
存储 JavaScript 前端开发
基于 SpringBoot 和 Vue 开发校园点餐订餐外卖跑腿Java源码
一个非常实用的校园外卖系统,基于 SpringBoot 和 Vue 的开发。这一系统源于黑马的外卖案例项目 经过站长的进一步改进和优化,提供了更丰富的功能和更高的可用性。 这个项目的架构设计非常有趣。虽然它采用了SpringBoot和Vue的组合,但并不是一个完全分离的项目。 前端视图通过JS的方式引入了Vue和Element UI,既能利用Vue的快速开发优势,
38 13
|
17天前
|
缓存 监控 Java
Java线程池提交任务流程底层源码与源码解析
【11月更文挑战第30天】嘿,各位技术爱好者们,今天咱们来聊聊Java线程池提交任务的底层源码与源码解析。作为一个资深的Java开发者,我相信你一定对线程池并不陌生。线程池作为并发编程中的一大利器,其重要性不言而喻。今天,我将以对话的方式,带你一步步深入线程池的奥秘,从概述到功能点,再到背景和业务点,最后到底层原理和示例,让你对线程池有一个全新的认识。
47 12
|
11天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
13天前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
17 1
|
26天前
|
JavaScript 前端开发 Java
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript和Vue的大一学生。如果你从我的文章中受益,欢迎关注我,我将持续更新更多优质内容。你的支持是我前进的动力!🎉🎉🎉
23 0
还不明白面向对象? 本文带你彻底搞懂面向对象的三大特征(2024年11月Java版)
|
29天前
|
Java Android开发
Eclipse 创建 Java 包
Eclipse 创建 Java 包
31 1
|
1月前
|
人工智能 监控 数据可视化
Java智慧工地信息管理平台源码 智慧工地信息化解决方案SaaS源码 支持二次开发
智慧工地系统是依托物联网、互联网、AI、可视化建立的大数据管理平台,是一种全新的管理模式,能够实现劳务管理、安全施工、绿色施工的智能化和互联网化。围绕施工现场管理的人、机、料、法、环五大维度,以及施工过程管理的进度、质量、安全三大体系为基础应用,实现全面高效的工程管理需求,满足工地多角色、多视角的有效监管,实现工程建设管理的降本增效,为监管平台提供数据支撑。
37 3