Java中级部分

news2025/3/3 18:21:34

以下内容来源自Java 面试指南 | JavaGuide(Java面试 + 学习指南)和自己的学习笔记整理,这里我整理了自己比较感兴趣的点,也有助于我自己理解~

异常

Exception 和 Error 有什么区别?

在 Java 中,所有的异常都有一个共同的祖先 java.lang 包中的 Throwable 类。Throwable 类有两个重要的子类:

  • Exception :程序本身可以处理的异常,可以通过 catch 来进行捕获。Exception 又可以分为 Checked Exception (受检查异常,必须处理) 和 Unchecked Exception (不受检查异常,可以不处理)。
  • ErrorError 属于程序无法处理的错误 ,我们没办法通过 catch 来进行捕获不建议通过catch捕获 。例如 Java 虚拟机运行错误(Virtual MachineError)、虚拟机内存不够错误(OutOfMemoryError)、类定义错误(NoClassDefFoundError)等 。这些异常发生时,Java 虚拟机(JVM)一般会选择线程终止。

著作权归Guide所有 原文链接:Java基础常见面试题总结(下) | JavaGuide(Java面试 + 学习指南)

也就是说,Exception程序本身可以处理,可能是我们哪里代码写错了,是可以用catch来捕获的;Error程序无法处理,JVM运行时出现了问题,也不能用catch捕获。

try-catch-finally 如何使用?

  • try块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。
  • catch块:用于处理 try 捕获到的异常。
  • finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

代码示例:

try {
    System.out.println("Try to do something");
    throw new RuntimeException("RuntimeException");
} catch (Exception e) {
    System.out.println("Catch Exception -> " + e.getMessage());
} finally {
    System.out.println("Finally");
}

输出:

Try to do something
Catch Exception -> RuntimeException
Finally

注意:不要在 finally 语句块中使用 return! 当 try 语句和 finally 语句中都有 return 语句时,try 语句块中的 return 语句会被忽略。这是因为 try 语句中的 return 返回值会先被暂存在一个本地变量中,当执行到 finally 语句中的 return 之后,这个本地变量的值就变为了 finally 语句中的 return 返回值。

jvm 官方文档open in new window中有明确提到:

If the try clause executes a return, the compiled code does the following:

  1. Saves the return value (if any) in a local variable.
  2. Executes a jsr to the code for the finally clause.
  3. Upon return from the finally clause, returns the value saved in the local variable.

代码示例:

public static void main(String[] args) {
    System.out.println(f(2));
}

public static int f(int value) {
    try {
        return value * value;
    } finally {
        if (value == 2) {
            return 0;
        }
    }
}

输出:

0

著作权归Guide所有 原文链接:Java基础常见面试题总结(下) | JavaGuide(Java面试 + 学习指南)

此外,finally中的代码不一定会被执行,比如如果在finally之前JVM被终止运行,finally中的代码就不会被执行~还有就是程序所在的线程死亡、CPU关闭都会导致finally中的代码不会被执行。

反射

Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得==任何类的内部信息==,并能直接操作任意对象的内部属性及方法。

也就是说通过反射我们可以获取任意一个类的所有属性和方法,还可以调用这些方法和属性。

像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。

反射优点和缺点

优点:

  • 可以实现动态创建对象和编译,体现出很大的灵活性,是很多开源框架开箱即用的原因。

缺点:

  • 对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。但是对框架影响不大。

所以我觉得还是优点大于缺点的,便利!

获取 Class 对象的四种方式

如果我们动态获取到这些信息,我们需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。Java 提供了四种方式获取 Class 对象:

1. 知道具体类的情况下可以使用:该方法最为可靠,程序性能最高

Class alunbarClass = TargetObject.class;

但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取 Class 对象不会进行初始化

2. 通过 Class.forName()传入类的全路径获取:

Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");

3. 通过对象实例instance.getClass()获取:

TargetObject o = new TargetObject();
Class alunbarClass2 = o.getClass();

4. 通过类加载器xxxClassLoader.loadClass()传入类路径获取:

ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject");

通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执行


著作权归Guide所有 原文链接:Java 反射机制详解 | JavaGuide(Java面试 + 学习指南)

类加载器是一个点,在后面详细看看。

注解

何谓注解?

Annotation (注解) 是 Java5 开始引入的新特性,可以看作是一种特殊的注释,主要用于修饰类、方法或者变量,提供某些信息供程序在编译或者运行时使用。

注解本质是一个继承了Annotation 的特殊接口:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {

}

public interface Override extends Annotation{

}

JDK 提供了很多内置的注解(比如 @Override@Deprecated),同时,我们还可以自定义注解。

不是程序本身,可以对程序作出解释,可以被其他程序读取如编译器,注释是给人看的,注解不光给人看,还要给程序(机器)解读

内置注解:

  • @Override:定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中另一个方法声明。
  • @Deprecated:定义在java.lang.Deprecated中,此注释可以用于修辞方法,属性,类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或者存在更好的选择。
  • … …

注解的解析方法有哪几种?

注解只有被解析之后才会生效,常见的解析方法有两种:

  • 编译期直接扫描:编译器在编译 Java 代码的时候扫描对应的注解并处理,比如某个方法使用@Override 注解,编译器在编译的时候就会检测当前的方法是否重写了父类对应的方法。
  • 运行期通过反射处理:像框架中自带的注解(比如 Spring 框架的 @Value@Component)都是通过反射来进行处理的。

著作权归Guide所有 原文链接:Java基础常见面试题总结(下) | JavaGuide(Java面试 + 学习指南)

SPI

SPI 即 Service Provider Interface ,字面意思就是:“服务提供者的接口”,我的理解是:专门提供给服务提供者或者扩展框架功能的开发者去使用的一个接口。

SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服务实现者解耦,能够提升程序的扩展性、可维护性。修改或者替换服务实现并不需要修改调用方。

很多框架都使用了 Java 的 SPI 机制,比如:Spring 框架、数据库加载驱动、日志接口、以及 Dubbo 的扩展实现等等。


著作权归Guide所有 原文链接:Java基础常见面试题总结(下) | JavaGuide(Java面试 + 学习指南)

SPI 和 API 有什么区别?

那 SPI 和 API 有啥区别?

说到 SPI 就不得不说一下 API 了,从广义上来说它们都属于接口,而且很容易混淆。下面先用一张图说明一下:

img

一般模块之间都是通过接口进行通讯,那我们在服务调用方和服务实现方(也称服务提供者)之间引入一个“接口”。

当实现方提供了接口和实现,我们可以通过调用实现方的接口从而拥有实现方给我们提供的能力,这就是 API ,这种接口和实现都是放在实现方的。

当接口存在于调用方这边时,就是 SPI ,由接口调用方确定接口规则,然后由不同的厂商去根据这个规则对这个接口进行实现,从而提供服务

举个通俗易懂的例子:公司 H 是一家科技公司,新设计了一款芯片,然后现在需要量产了,而市面上有好几家芯片制造业公司,这个时候,只要 H 公司指定好了这芯片生产的标准(定义好了接口标准),那么这些合作的芯片公司(服务提供者)就按照标准交付自家特色的芯片(提供不同方案的实现,但是给出来的结果是一样的)。

所以我的理解就是我们使用这个接口,然后厂商根据我们的需求(规则)来提供这个接口不同的实现方法,为我们提供服务。

SPI 的优缺点?

通过 SPI 机制能够大大地提高接口设计的灵活性,但是 SPI 机制也存在一些缺点,比如:

  • 需要遍历加载所有的实现类,不能做到按需加载,这样效率还是相对较低的。
  • 当多个 ServiceLoader 同时 load 时,会有并发问题

序列化

什么是序列化和反序列化?

如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。

简单来说:

  • 序列化:将数据结构或对象转换成二进制字节流的过程
  • 反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程

对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class),但是在 C++这种半面向对象的语言中,struct(结构体)定义的是数据结构类型,而 class 对应的是对象类型。

下面是序列化和反序列化常见应用场景:

  • 对象在进行网络传输(比如远程方法调用 RPC 的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
  • 将对象存储到文件之前需要进行序列化,将对象从文件中读取出来需要进行反序列化;
  • 将对象存储到数据库(如 Redis)之前需要用到序列化,将对象从缓存数据库中读取出来需要反序列化;
  • 将对象存储到内存之前需要进行序列化,从内存中读取出来之后需要进行反序列化。

维基百科是如是介绍序列化的:

序列化(serialization)在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。依照序列化格式重新获取字节的结果时,可以利用它来产生与原始对象相同语义的副本。对于许多对象,像是使用大量引用的复杂对象,这种序列化重建的过程并不容易。面向对象中的对象序列化,并不概括之前原始对象所关系的函数。这种过程也称为对象编组(marshalling)。从一系列字节提取数据结构的反向操作,是反序列化(也称为解编组、deserialization、unmarshalling)。

综上:序列化的主要目的是通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。

img

https://www.corejavaguru.com/java/serialization/interview-questions-1

序列化协议对应于 TCP/IP 4 层模型的哪一层?

我们知道网络通信的双方必须要采用和遵守相同的协议。TCP/IP 四层模型是下面这样的,序列化协议属于哪一层呢?

  1. 应用层
  2. 传输层
  3. 网络层
  4. 网络接口层

TCP/IP 四层模型TCP/IP 四层模型

如上图所示,OSI 七层协议模型中,表示层做的事情主要就是对应用层的用户数据进行处理转换为二进制流。反过来的话,就是将二进制流转换成应用层的用户数据。这不就对应的是序列化和反序列化么?

因为,OSI 七层协议模型中的应用层、表示层和会话层对应的都是 TCP/IP 四层模型中的应用层,所以序列化协议属于 TCP/IP 协议应用层的一部分。


著作权归Guide所有 原文链接:https://javaguide.cn/java/basis/serialization.html

使用流传输对象的过程叫做序列化、反序列化,当我们需要把内存中的对象写入到硬盘或者通过网络进行传输时,就需要序列化,反过来则需要反序列化操作来对网络上或者硬盘中的对象进行读取。

并且在TCP/IP 4 层模型中,序列化、反序列化对应的是应用层。

示层和会话层对应的都是 TCP/IP 四层模型中的应用层,所以序列化协议属于 TCP/IP 协议应用层的一部分。


著作权归Guide所有 原文链接:https://javaguide.cn/java/basis/serialization.html

使用流传输对象的过程叫做序列化、反序列化,当我们需要把内存中的对象写入到硬盘或者通过网络进行传输时,就需要序列化,反过来则需要反序列化操作来对网络上或者硬盘中的对象进行读取。

并且在TCP/IP 4 层模型中,序列化、反序列化对应的是应用层。

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

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

相关文章

【学习笔记之vue】 Cannot find module ‘node-sass‘

Cannot find module node-sass方案一(不通) 下载node-sass组件 >> npm install -g cnpm>>cnpm install node-sass下载时报错 方案二 使用npm下载node-sass组件 >>npm install node-sassok

Oracle字段长度不足位数补零

Oracle字段长度不足位数补零 有时候从数据库中取出的月份值是1&#xff0c;而不是01&#xff0c;该怎么办呢 SELECTLPAD( CODE_MONTH, 2, 0 ) FROMtb_cube_TY001 WHERECODE_BM_MEATYPE TY20 AND code_measure MYLX01 AND code_month <> ~ AND CODE_ENTITY 01A AND…

Linux 进程间通信——信号量

一、信号量描述 信号量是一个特殊的变量&#xff0c;一般取正数值。它的值代表允许访问的资源数目。 获取资源时&#xff0c;需要对信号量的值进行原子减一&#xff0c;该操作被称为P操作&#xff0c;当信号量值为0时&#xff0c;代表没有资源可用&#xff0c;P操作会阻塞。释…

2023一建案例100题

一、某施工单位承接了两栋住宅楼&#xff0c;总建筑面积 65000m&#xff0c;均为筱板基础(上翻梁结构)&#xff0c;地下 2层&#xff0c;地上30 层&#xff0c;地下结构连通&#xff0c;上部为两个独立单体一字设置&#xff0c;设计形式一致&#xff0c;地下室外墙南北向距离 4…

008永磁电机FOC控制:磁场定向控制不就两个变换就搞定啦

在现代工业中&#xff0c;电机广泛应用于各类设备和机械系统中。为了提高电机性能并降低能量损耗&#xff0c;电机控制技术得到了不断的发展和创新。其中&#xff0c;磁场定向控制&#xff08;Field-Oriented Control&#xff0c;简称FOC&#xff09;作为一种先进的电机控制策略…

在 IDEA 中使用 Git开发 图文教程

在 IDEA 中使用 Git开发 图文教程 一、连接远程仓库二、IDEA利用Git进行开发操作三、分支操作3.1 新建分支3.2 切换分支3.3 删除分支3.4 比较分支3.5 合并分支 四、常用快捷键 一、连接远程仓库 一、打开IDEA&#xff0c;进入目录&#xff1a;File ->New ->Project from…

PHP之Base64+php://filter绕过、disabled_function绕过

目录 一、Base64php://filter绕过 1.思路分析 2.实践验证 二、disabled_function绕过 一、Base64php://filter绕过 上课讲了这样一道题&#xff0c;一起来看下(以下代码适用于PHP7.x及以上&#xff0c;5的版本会报错) <?php function fun($var): bool{$blacklist …

STM32 中断复习

中断 打断CPU执行正常的程序&#xff0c;转而处理紧急程序&#xff0c;然后返回原暂停的程序继续运行&#xff0c;就叫中断。 在确定时间内对相应事件作出响应&#xff0c;如&#xff1a;温度监控&#xff08;定时器中断&#xff09;。故障处理&#xff0c;检测到故障&#x…

详细讲解什么是SpringMVC 映射请求数据

&#x1f600;前言 本文详细讲解什么是SpringMVC 映射请求数据 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f609; …

2023年03月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:数字字符求和 请编写一个程序实现以下功能:从一个字符串中,提取出所有的数字字符即0-9,并作为数求和。 时间限制:1000 内存限制:65536 输入 一行字符串,长度不超过100,字符串中不含空格。 输出 字符串中所有数字字符作为数的和 样例输入 Lsd2f02k3ja3sdf223 样例…

辅助笔记-安装Ubantu虚拟机

安装Ubantu虚拟机 文章目录 安装Ubantu虚拟机步骤一&#xff1a;检查BIOS虚拟化支持步骤二&#xff1a;VMware17安装虚拟机步骤1&#xff1a;新建虚拟机步骤2&#xff1a;验证虚拟机能否上网 步骤3&#xff1a;设置Ubantu语言为中文 本文主要参考B站视频“P108_ 韩顺平Linux_ u…

测评类软文怎么写?教你几招

测评类种草软文&#xff0c;是当下非常热门的一种文章类型。这类文章以其独特的魅力&#xff0c;吸引着大量的用户&#xff0c;同时也让许多商家看到了商机。然而&#xff0c;如何写好一篇测评类种草软文&#xff0c;却是许多企业和品牌面临的难题。接下来伯乐网络传媒就给大家…

如何制作gif动图表情包?教你一键在线生成gif动图

使用gif表情的时候&#xff0c;经常发现市面上的表情包不太符合自己的需求&#xff0c;这时候我们可以动手制作自己的表情包&#xff0c;如何才能快速完成gif图片制作呢&#xff1f;今天就教大家一个不用下载安装任何软件的方法&#xff0c;使用专业的在线gif生成功能来制作gif…

代码随想录第24天|初步了解回溯三部曲

回溯是递归的副产品&#xff0c;只要有递归就会有回溯。 所以以下讲解中&#xff0c;回溯函数也就是递归函数&#xff0c;指的都是一个函数。 提到了回溯法的效率&#xff0c;回溯法其实就是暴力查找&#xff0c;并不是什么高效的算法。 最后我们讲到回溯法解决的问题都可以…

SIP网络音频模块-sip网络对讲音频模块(提供POE受电模块接口)

SIP网络音频模块-sip网络对讲音频模块&#xff08;提供POE受电模块接口&#xff09; SIP网络音频模块SV-2401V网络对讲音频模块&#xff08;支持POE&#xff09; SV-2403V网络对讲音频模块_网络语音对讲模块 网络音频模块 双向对讲 SIP广播系统 SIP网络音频模块嵌入式网络对…

花生十三 判断推理(四)定义判断、类比推理

定义判断 解题思路&#xff1a; 不是单纯的连连看&#xff0c;重在理解&#xff0c;可联系生活中的人或事或某种现象 题型特征&#xff1a;“被定义词” 解释 关键信息 “被定义词” &#xff1a;因名包含有重要特征特别关注&#xff1a;主体、对象、特殊要求、中心语 选…

真香!主数据管理系统,企业大哥必备神器

什么是主数据&#xff1f; 当一家连锁商超企业的市场营销部门想要策划一场线上线下营销活动&#xff0c;从而为消费者提供便捷的购物体验&#xff0c;就需要掌握商超会员的数据。 要想拥有这些数据就需掌握顾客的交易行为&#xff0c;掌握其购物过程行为&#xff0c;甚至情感…

Serverless 应用托管助力企业加速创新

作者&#xff1a;熊峰 云原生时代的 Serverless 应用托管架构 回顾过去十年&#xff0c;数字化转型将科技创新与商业元素不断融合、重构&#xff0c;重新定义了新业态下的增长极。商业正在从大工业时代的固化范式进化成面向创新型商业组织与新商业物种的崭新模式。随着数字化转…

操作符详解上(非常详细)

目录 二进制介绍二进制2进制转10进制10进制转2进制数字2进制转8进制和16进制2进制转8进制2进制转16进制 原码、反码、补码移位操作符左移操作符右移操作符 位操作符&#xff1a;&、|、^逗号表达式 二进制介绍 在初学计算机时我们常常会听到2进制、8进制、10进制、16进制……

PiplineADC学习一:

PiplineADC结构&#xff1a; PiplineADC起源之FlashADC PiplineADC起源之Sub-Ranging-ADC 比较器存在失调&#xff1a; 因此每级1bit不实用&#xff0c;需要做冗余位设计。 多比较一次&#xff0c;两个阈值&#xff0c;三个区间&#xff0c;分别对于输出00,01,10。正常2bit应该…