Java 中 又一个你天天使用,但是不一定知道的知识点

简介: 大家都知道当我们在进行条件判断的时候除了可以使用 if-else 之外,还可以是用 switch,而且在 JDK 7 之后在 switch 中还增加了 String 类型的支持,如下代码所示。

大家都知道当我们在进行条件判断的时候除了可以使用 if-else 之外,还可以是用 switch,而且在 JDK 7 之后在 switch 中还增加了 String 类型的支持,如下代码所示。

public static void testSwitch(String language) {
        switch (language) {
            case "C++":
                System.out.println("C++");
                break;
            case "Java":
                System.out.println("Java");
                break;
            case "Python":
                System.out.println("Python");
            default:
                System.out.println("default");
                break;
        }
    }

如果还不知道可以这样用的小伙伴,那你今天知道了,不过阿粉相信小伙伴都知道这个特性,但是这里阿粉提两个问题,看看聪明的你能不能答出来。

  1. 如果 languagenull,即 testSwitch(null) 会输出什么?
  2. swtich() 支持String 的原理是什么?

看到这里请停下来,思考五秒钟

5

4

3

2

1

好,我们来看下上面两个问题,首先如果对于问题一你要是回答会输出default 那么阿粉告诉你,这是错误的。不信的话,我们实践一下,毕竟实践是检验真理的唯一标准。

40.jpg

从上面的输出我们可以看到,已经报了空指针的异常了,到这里可能有些小伙伴就疑惑了,上面的代码看起来没什么特别的啊,null 传进去应该走到 default 分支才对啊,为什么会报空指针呢?有这个疑问的小伙伴也不要捉急,看完第二个问题的答案,你就知道为什么了。

同样的要搞清楚为什么问题一的答案是空指针,我们就需要知道 switch 中支持 String 的原理是什么。下面我们来看看第二个问题。首先我们将这个代码通过 Javac 编译一下,执行命令:javac SwitchTest.java,我们就可以得到编译后的 SwitchTest.class 文件,再通过反编译我们可以得到下面的内容,这里反编译可以直接将 class 文件拖进 idea 中即可。

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.fenixsoft.clazz;
public class SwitchTest {
    public SwitchTest() {
    }
    public static void main(String[] var0) {
        testSwitch((String)null);
    }
    public static void testSwitch(String var0) {
        byte var2 = -1;
        switch(var0.hashCode()) {
        case -1889329924:
            if (var0.equals("Python")) {
                var2 = 2;
            }
            break;
        case 65763:
            if (var0.equals("C++")) {
                var2 = 0;
            }
            break;
        case 2301506:
            if (var0.equals("Java")) {
                var2 = 1;
            }
        }
        switch(var2) {
        case 0:
            System.out.println("C++");
            break;
        case 1:
            System.out.println("Java");
            break;
        case 2:
            System.out.println("Python");
        default:
            System.out.println("default");
        }
    }
}

到这里相信大家就知道为什么了,很显然 Switch 支持 String 底层的原理是使用了 Stringhasecodeequals 方法。通过得到入参字符串的 hasecode 来决定进入哪个分支。大家都知道 hasecode 的返回值是 int 类型,所以说即使传入的参数类型的字符串,底层还是使用的整型来进行判断的。

而且到这里,大家也知道了为什么问题一的答案是会出现空指针了,因为这里在调用 hasecode 的时候,很明显会出现空指针异常

这就告诉我们在进行 switch string 的使用的时候,一定要进行入参的非 NULL 校验,这一点在阿里巴巴的手册中也有明确的强制要求。

41.jpg

公众号回复【Java】获取阿里巴巴 Java 开发手册——华山版。

同时通过上面反编译后的代码,我们也可以看到,参数 String 是区分大小写的,因为里面使用了 equals 进行判断,所以我们也要注意字符串的大小写,避免出现问题。

为了验证是真的是采用 hasecode ,我们可以将上面代码中涉及到了几个字符串的 hasecode 输出出来验证一下。

public static void main(String[] args) {
//        testSwitch(null);
        System.out.println("C++".hashCode());
        System.out.println("Java".hashCode());
        System.out.println("Python".hashCode());
    }


42.jpg

可以看到输出的 hasecode 和反编译后的 hasecode 是一致的。

看到这里的小伙伴我们再延伸一下,既然这里是在编译时期就生成了 hasecode ,那说明我们不能传入一个动态生成的字符串,也就是下面的写法会无法通过编译。

43.jpg

虽然看上去都是一个字符串,但是明显这种形式是不行的,因为没办法在编译的时候就获得 hasecode,自然也就不可以这些写了,相信小伙伴们在之前写代码的时候也遇到过这种情况,但是当时可能并不知道是为什么,只知道要定义个常量或者字符串字面量,相信看完这篇文章的你,就知道是为什么了。

总结一下今天阿粉带大家看了一个 Switch String 类型参数的实现原理,有些知识点在我们平时工作中虽然会经常用到,但是并不会深入去研究原理,相信通过今天阿粉的这篇文章,会对大家有所帮助,如果觉得文章有帮助的话,请大家点赞,分享,评论,在看,不要怕被其他小伙伴看到,更多优质的原创文章欢迎关注我们 Java 极客技术。

相关文章
|
3月前
|
IDE Java 开发工具
Java 基础篇必背综合知识点最新技术与实操应用全面总结指南
本总结梳理了Java 17+的核心知识点与新技术,涵盖基础概念(模块化系统、GraalVM)、数据类型(文本块、模式匹配)、流程控制(增强switch)、面向对象(Record类、密封类)、常用类库(Stream API、HttpClient)、实战案例(文件处理)、构建工具(Maven、Gradle)、测试框架(JUnit 5)、开发工具(IDE、Git)及云原生开发(Spring Boot 3、Docker)。通过理论结合实操,帮助开发者掌握Java最新特性并应用于项目中。代码示例丰富,建议配合实践加深理解。
95 4
|
2月前
|
Java 数据库连接 数据库
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
本文全面总结了Java核心知识点,涵盖基础语法、面向对象、集合框架、并发编程、网络编程及主流框架如Spring生态、MyBatis等,结合JVM原理与性能优化技巧,并通过一个学生信息管理系统的实战案例,帮助你快速掌握Java开发技能,适合Java学习与面试准备。
99 2
Java 相关知识点总结含基础语法进阶技巧及面试重点知识
|
2月前
|
存储 Java 程序员
Java 基础知识点全面梳理包含核心要点及难点解析 Java 基础知识点
本文档系统梳理了Java基础知识点,涵盖核心特性、语法基础、面向对象编程、数组字符串、集合框架、异常处理及应用实例,帮助初学者全面掌握Java入门知识,提升编程实践能力。附示例代码下载链接。
87 1
|
2月前
|
Java 编译器 数据安全/隐私保护
Java 大学期末考试真题与答案 含知识点总结 重难点归纳及题库汇总 Java 期末备考资料
本文汇总了Java大学期末考试相关资料,包含真题与答案、知识点总结、重难点归纳及题库,涵盖Java基础、面向对象编程、异常处理、IO流等内容,并提供完整代码示例与技术方案,助你高效复习备考。
81 3
|
2月前
|
存储 缓存 安全
Java基础 - 知识点
Java基础知识点涵盖语言特性、面向对象与基本数据类型、缓存池机制、String类特性、参数传递、类型转换、继承、抽象类与接口区别、重写与重载、Object通用方法及关键字使用等核心内容,是掌握Java编程的重要基石。
|
3月前
|
存储 安全 Java
2025 年最新 40 个 Java 基础核心知识点全面梳理一文掌握 Java 基础关键概念
本文系统梳理了Java编程的40个核心知识点,涵盖基础语法、面向对象、集合框架、异常处理、多线程、IO流、反射机制等关键领域。重点包括:JVM运行原理、基本数据类型、封装/继承/多态三大特性、集合类对比(ArrayList vs LinkedList、HashMap vs TreeMap)、异常分类及处理方式、线程创建与同步机制、IO流体系结构以及反射的应用场景。这些基础知识是Java开发的根基,掌握后能为后续框架学习和项目开发奠定坚实基础。文中还提供了代码资源获取方式,方便读者进一步实践学习。
511 2
|
3月前
|
并行计算 Java API
Java 入门循环结构基础知识点详解
摘要:本文介绍了Java现代循环技术的进阶应用,包括Stream API、响应式编程和模式匹配,展示了如何用Stream API替代传统循环进行声明式集合处理(如过滤、映射和并行计算),以及响应式编程在异步非阻塞场景下的优势。文章还通过电商订单处理系统的案例演示了这些技术的综合应用,并提供了性能优化建议,如合理使用并行处理和避免循环内对象创建。这些现代特性使Java代码更简洁、高效,更适合高并发和I/O密集型场景。
45 1
|
3月前
|
缓存 算法 NoSQL
校招 Java 面试高频常见知识点深度解析与实战案例详细分享
《2025校招Java面试核心指南》总结了Java技术栈的最新考点,涵盖基础语法、并发编程和云原生技术三大维度: 现代Java特性:重点解析Java 17密封类、Record类型及响应式Stream API,通过电商案例演示函数式数据处理 并发革命:对比传统线程池与Java 21虚拟线程,详解Reactor模式在秒杀系统中的应用及背压机制 云原生实践:提供Spring Boot容器化部署方案,分析Spring WebFlux响应式编程和Redis Cluster缓存策略。
68 0
|
2月前
|
缓存 安全 前端开发
Java 核心知识点与实战应用解析
我梳理的这些内容涵盖了 Java 众多核心知识点。包括 final 关键字的作用(修饰类、方法、变量的特性);重载与重写的区别;反射机制的定义、优缺点及项目中的应用(如结合自定义注解处理数据、框架底层实现)。 还涉及 String、StringBuffer、StringBuilder 的差异;常见集合类及线程安全类,ArrayList 与 LinkedList 的区别;HashMap 的实现原理、put 流程、扩容机制,以及 ConcurrentHashMap 的底层实现。 线程相关知识中,创建线程的四种方式,Runnable 与 Callable 的区别,加锁方式(synchronize
|
3月前
|
算法 安全 Java
2025 校招必看:Java 开发面试核心知识点深度解析及最新笔面试题汇总
本文针对2025校招Java开发面试,系统梳理了Java基础、集合框架、多线程并发、JVM等核心知识点,并附带最新笔面试题。内容涵盖封装、继承、多态、异常处理、集合类使用、线程同步机制、JVM内存模型及垃圾回收算法等。同时深入探讨Spring、数据库(MySQL索引优化、Redis持久化)、分布式系统(CAP理论、分布式事务)等相关知识。通过理论结合实例解析,帮助考生全面掌握面试要点,提升实战能力,为成功拿下Offer奠定坚实基础。
308 3

热门文章

最新文章