面试题:switch语句能否作用在byte上,能否作用在long上,能否作用在String上?

switch语句能否作用在byte上,能否作用在long上,能否作用在String上 2、switch语句能否作用在byte上,能否作用在long上,能否作用在String上    在switch(expr1)中,expr1只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为int,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。 立即下载

/**
 * 问题:switch语句能否作用在byte上,能否作用在long上,能否作用在String上
 * 基本类型的包装类(如:Character、Byte、Short、Integer)
 * 
 * switch可作用于char byte short int
 * switch可作用于char byte short int对应的包装类
 * switch不可作用于long double float boolean,包括他们的包装类
 * switch中可以是字符串类型,String(jdk1.7之后才可以作用在string上)
 * switch中可以是枚举类型

 */

 

java基础(六) switch语句的深入解析

 

引言

  switch 语句是非常的基础的知识,掌握起来也不难掌握,语法比较简单。但大部分人基本是知其然,不知其所以然。譬如 早期JDK只允许switch的表达式的值 int及int类型以下的基本类型,后期的JDK却允许匹配比较 字符串、枚举类型,这是怎么做到的呢?原理是什么?本文将深入去探索。

一、switch 介绍

switch 语法格式:

 switch (表达式) {
		case 常量表达式或枚举常量:
			语句;
			break;
		case 常量表达式或枚举常量:
			语句;
			break;
		......
		default: 语句;
			break;
	}

switch 匹配的表达式可以是:

  • byte、short、char、int类型及 这4种类型的包装类型;
  • 枚举类型;
  • String 类型;

case 匹配的表达式可以是:

  • 常量表达式;
  • 枚举常量;

注意一点: case提供了switch表达式的入口地址,一旦switch表达式与某个case分支匹配,则从该分支的语句开始执行,一直执行下去,即其后的所有case分支的语句也会被执行,直到遇到break语句。

看个例子体会一下:

public static void main(String[] args) {
		String  s = "a";
		
        switch (s) {
		case "a": //a分支
			 System.out.println("匹配成功1");
			    
		case "b": //b分支
		        System.out.println("匹配成功2");
		        
		case "c": //c分支
		         System.out.println("匹配成功3");
		         break;
		case "d": //d分支
		         System.out.println("匹配成功4");
		         break;
		default:
			break;
		}
	}

运行结果:

匹配成功1
匹配成功2
匹配成功3

  switch成功匹配了a分支,但a、b分支都没有 break 语句,所以一直执行a分支后的所有语句,直到遇到c分支的break语句才终止。

二、编译器对 switch 表达式的各种类型的处理

  尽管 switch 支持的类型扩充了几个,但其实在底层中,swtich 只能支持4种基本类型,其他几个类型是通过一些方式来间接处理的,下面便是讲解编译器对扩充类型的处理。

1、对包装类的处理

  对包装类的处理是最简单的 —— 拆箱。看下面的例子,switch 比较的是包装类 Byte 。

		Byte b = 2;

		switch (b) {

		case 1:
			System.out.println("匹配成功");
			break;
		case 2:
			System.out.println("匹配成功");
			break;
		}

用jad反编译一下这段代码,得到的代码如下:

        Byte b = Byte.valueOf((byte)2);

        switch(b.byteValue())
        {
        case 1: // '\001'
            System.out.println("\u5339\u914D\u6210\u529F");
            break;

        case 2: // '\002'
            System.out.println("\u5339\u914D\u6210\u529F");
            break;
        }

  反编译的代码很简单,底层的switch比较的是Byte通过(拆箱)方法byteValue()得到的byte值。顺便说一下,这段反编译代码不仅揭开了 拆箱 的解析原理,也展示了 装箱 的解析原理(第一句代码);

2. 枚举类型

为了简单起见,直接采用JDK提供的枚举类型的线程状态类 Thread.state 类。

	Thread.State state = Thread.State.RUNNABLE;
		
	switch (state) {
	case NEW:
		System.out.println("线程处于创建状态");
		break;
	case RUNNABLE:
		System.out.println("线程处于可运行状态");
		break;
	case TERMINATED:
		System.out.println("线程结束");
		break;

	default:
		break;
}

反编译代码:

Sex sex = Sex.MALE;
        switch($SWITCH_TABLE$Test_2018_1_14$Sex()[sex.ordinal()])
        {
        case 1: // '\001'
            System.out.println("sex:male");
            break;

        case 2: // '\002'
            System.out.println("sex:female");
            break;
        }

  从编译代码中发现,编译器对于枚举类型的处理,是通过创建一个辅助数组来处理,这个数组是通过一个$SWITCH_TABLE$java$lang$Thread$State() 方法创建的,数组是一个int[]类型数组,数组很简单,在每个枚举常量的序号所对应的数组下标位置的赋一个值,按序号大小赋值,从1开始递增。 其代码如下:

//int 数组
private static int $SWITCH_TABLE$java$lang$Thread$State[];

//创建数组的方法
static int[] $SWITCH_TABLE$java$lang$Thread$State()
    {
        $SWITCH_TABLE$java$lang$Thread$State;
        if($SWITCH_TABLE$java$lang$Thread$State == null) goto _L2; else goto _L1
_L1:
        return;
_L2:
        JVM INSTR pop ;
        int ai[] = new int[Thread.State.values().length];
        try
        {
            ai[Thread.State.BLOCKED.ordinal()] = 3;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[Thread.State.NEW.ordinal()] = 1;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[Thread.State.RUNNABLE.ordinal()] = 2;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[Thread.State.TERMINATED.ordinal()] = 6;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[Thread.State.TIMED_WAITING.ordinal()] = 5;
        }
        catch(NoSuchFieldError _ex) { }
        try
        {
            ai[Thread.State.WAITING.ordinal()] = 4;
        }
        catch(NoSuchFieldError _ex) { }
        return $SWITCH_TABLE$java$lang$Thread$State = ai;
    }
}

3、 对String类型的处理

依旧是先看个例子,再查看这个例子反编译代码,了解编译器的是如何解析的。

public static void main(String[] args) {
		String  s = "China";
		
        switch (s) {
		case "America": 
			     System.out.println("匹配到美国");
			     break;
		case "China": 
		        System.out.println("匹配到中国");
		        break;
		case "Japan": 
		         System.out.println("匹配到日本");
		default:
			break;
		}
	}

反编译得到的代码:

  public static void main(String args[])
    {
        String s = "China";
        String s1;
        switch((s1 = s).hashCode())
        {
        default:
            break;

        case 65078583: 
            if(s1.equals("China"))
                System.out.println("\u5339\u914D\u5230\u4E2D\u56FD");
            break;

        case 71341030: 
            if(s1.equals("Japan"))
                System.out.println("\u5339\u914D\u5230\u65E5\u672C");
            break;

        case 775550446: 
            if(s1.equals("America"))
                System.out.println("\u5339\u914D\u5230\u7F8E\u56FD");
            break;
        }
    }

  从反编译的代码可以看出,switch 的String变量、case 的String常量都变成对应的字符串的 hash 值。也就是说,switch仍然没有超出它的限制,只是通过使用 String对象的hash值来进行匹配比较,从而支持 String 类型。

总结:

  • 底层的switc只能处理4个基本类型的值。其他三种类型需要通过其他方式间接处理,即转成基本类型来处理。
  • 编译器对包装类的处理是通过 拆箱。
  • 对枚举类型的处理,是通过枚举常量的序号及一个数组。
  • 对字符串String的处理,是通过 String 的hash值。

 

 

switch的转换和具体系统实现有关,如果分支比较少,可能会转换为跳转指令(条件跳转指令和无条件跳转指令)。但如果分支比较多,使用条件跳转会进行很多次的比较运算,效率比较低,可能会使用一种更为高效的方式,叫跳转表。跳转表是一个映射表,存储了可能的值以及要跳转到的地址,形如:

值1代码块1的地址
值2代码块2的地址
... 
值n代码块n的地址

跳转表为什么会更为高效呢?因为,其中的值必须为整数,且按大小顺序排序。按大小排序的整数可以使用高效的二分查找,即先与中间的值比,如果小于中间的值则在开始和中间值之前找,否则在中间值和末尾值之间找,每找一次缩小一倍查找范围,其算法复杂度为O(log2n)。

如果值是连续的,则跳转表还会进行特殊优化,优化为一个数组,连找都不用找了,值就是数组的下标索引,直接根据数组下标索引就可以找到跳转的地址。

即使值不是连续的,但数字比较密集,差的不多,编译器也可能会优化为一个数组型的跳转表,没有的值指向default分支。

 

程序源代码中的case值排列不要求是排序的,编译器会自动排序。switch判断的类型可以是byte, short, int, char, 枚举和String(java7及之后支持)。其中byte/short/int/char本来就是整数,而枚举类型也有对应的整数序号ordinal,String用于switch时也会通过hashCode方法转换为整数,为什么不可以使用long呢?因为跳转表值的存储空间一般为32位,容纳不下long。

需要说明下String的hashCode值可能冲突,而解决冲突的方式就是跳转之后再通过equals方法判定字符串内容是否相等。

 例如下面代码:

    String s = "123456";
    switch (s) {
    case "123": {
      System.out.println("s值为123");
    }
    }

编译后代码大概为:

    String s = "123456";
    String str1;
    switch ((str1 = s).hashCode())
    {
    case 48690: //48690是"123"的hashcode
      if (str1.equals("123")) {
        System.out.println("s值为123");
      }
    }

 

本文参考书籍《Java编程的逻辑》

转载于:https://www.cnblogs.com/JackPn/p/9382869.html

 

原文地址: https://www.cnblogs.com/jinggod/p/8425260.html

时序定江山,功耗写风骨——解读时序库lib文件的奥义【芯片设计 lib文件】 lib库,全称liberty library format file:它是Liberty时序文件的简称,使用 Liberty 语法来编写。它可以通过library compiler/dc转换成.db文件(database),供synopsis家的DC和PT使用,也可以通过spyglass的library compiler来生成sglib文件,供spyglass使用。他们是等价的,但db文件是二进制格式,人类不可读。 阅读详情

相关推荐

Vienna整流器双PI闭环仿真:从SVPWM调制到中点电位平衡的实践解析

本文深入解析Vienna整流器双PI闭环仿真技术,涵盖SVPWM调制和中点电位平衡的实践细节。通过详细的MATLAB/Simulink仿真搭建流程和常见问题排查方法,帮助工程师掌握高效整流器控制策略,提升系统稳定性和动态响应性能。

weixin_29168153的博客 328

switch是否能作用在byte上,是否能作用在long上,是否能作用在String上?

switch只能是int 或者能转化为int型的byte,short,char,jdk1.7之后String也可以。 在 switch( 表达式)中, 表达式 只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是 int 基本类型或 Integer 包装类型,由于byte,short,char 都可以自动转换(隐式转换)为 int,所以,这些类型以及这些类型 的包装类型也是可以的。显然, long 和 String 类型都不符合 switch 的语法规定,并且不能被隐式转换成 int 类型,所以,

dct的博客 2766

还在手敲LaTeX公式?用Rime小狼毫打造你的专属数学输入法(附完整配置包)

本文介绍如何利用Rime小狼毫输入法引擎打造专属数学公式输入方案,显著提升LaTeX公式输入效率。通过详细配置教程和智能补全技巧,帮助科研人员和学生实现3-5倍的输入速度提升,特别适合学术写作和技术文档创作场景。

weixin_32520601的博客 283

11、switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

switch只能时int 或这能转化为int型的,switch是只能用在int上面,但byte可以自动转型成int,可以用在byte上 而long字节比int字节多,不能隐式转化为int类型,所以switch语句可以用在byte上而不可以用在long上 String 类型都不符合 switch 的语法规定,并且不能被隐式转换成 int 新版本 JDK1.7 中引入新特性,所以 swtich 语句可以接收一个 String 类型的值, String 可以作用在 swtich 上。 ...

weixin_57442997的博客 1999

Openharmony 命令行工具hdc的获取与安装

OpenHarmony实战:命令行工具hdc安装应用指南_hdc工具-优快云博客t=N7T8。

Devlin_的博客 1万+

无人驾驶小车调试笔记(六)-- 车轮校准

简介:小车的动力完全来自于两个电机带动的车轮,在理想状态下,给两个电机同样的驱动参数,两个车轮会以同样的转速带动小车直线行驶,而实际情况是每个电机可能都会有个体差异,也就是说给予同样的驱动参数,表现出的转动速度会有些许不同,两个轮子的差速会导致车辆拐弯,后果就是给了直线行驶的控制命令,但是车走着走着就偏离了原本的方向,所以在开始控制之前,我们需要先平衡两个车轮的转速,保证在同样驱动参数下,两个车轮转速大致相同,也就是可以走直线。 车轮校准分为3步,测试、调整后再测试、保存参...

aibingjin的博客 1823

Java面试题 switch能否用于byte、long、String上?

switch能否作用于byte、long、String上? 可以作用于byte上,不能作用于long上,switch中可以是字符串类型,String(jdk1.7之后可以作用在String上)。 扩展总结: switch可以作用于:char、byte、short、int switch可以作用于:char、byte、short、int 对应的包装类 switch不可以作用于:long、double、float、boolean,包括它们的包装类 ...

单枪匹码 3254

损失函数大汇总(三十八)(AUCPR Loss附公式推导与代码)

本文系统介绍了AUCPR Loss的原理与应用。针对不平衡分类任务中AUC指标不够敏感的问题,提出通过优化PR曲线面积(AUCPR)来提升模型性能。文章详细推导了AUCPR的可微近似实现:首先用sigmoid函数软化阈值判断,构造可微的TP/FP/FN计数;然后基于软Precision和Recall计算近似PR曲线面积;最后通过数值积分得到可优化的损失函数。特别讨论了温度参数τ对训练稳定性的影响,并比较了AUCPR与AUC、AP等指标的异同。该方法适用于医学筛查、欺诈检测等极端不平衡场景,能更准确反映模型对

悦学共鸣,温柔以待,汇聚光芒,共同成长 442

【Java面试题】switch 是否能作用在byte上,是否能作用在long上,是否能作用在String上?

Java面试题:switch 是否能作用在byte上,是否能作用在long上,是否能作用在String上? switch 可作用于char byte short int switch 可作用于 char byte short int 对应的包装类 switch 不可作用于 long double float boolean 包括他们的包装类 switch 可作用于 String (jdk1.7 ...

不负年华 2597

Dify 第 3 篇 Dify 入门示例 - 聊天助手

本文介绍了如何使用Dify平台快速搭建一个聊天助手。首先通过创建空白应用并选择"聊天助手"模板完成基础设置,然后安装配置通义千问等大语言模型(LLM)并设置API密钥。进阶部分演示了如何创建支持编程语言选择的代码解释器,包括添加提示词约束、插入变量、设置开场白等功能。最后展示了运行效果:用户可选择编程语言后输入代码,系统会给出相应解释。文章还提到应用支持发布共享,并附有Dify官方文档参考链接。

甘蓝的专栏 864

使用Simulink进行基于IIR滤波器的设计与稳定性分析仿真

IIR滤波器的稳定性与其系统函数的极点位置密切相关。如果所有极点都位于Z平面的单位圆内,则该滤波器是稳定的;否则,滤波器将是不稳定的。在设计IIR滤波器时,确保其稳定性对于避免输出信号发散至关重要。明确你的系统需求,比如输入信号类型(如正弦波)、采样率、IIR滤波器的设计参数(如滤波器类型、阶数、截止频率等)。假设我们需要设计一个低通IIR滤波器,用来去除高于500Hz的所有频率成分,保留低于500Hz的信号成分。采样率为8kHz。

xiaoheshang_123的博客 151

java面试篇5、switch 语句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

switch语句可以作用在bytecharshortint和String类型上。switch语句不能作用在long类型上。从 Java 7 开始,switch语句可以作用在String类型上。

weixin_45422672的博客 352

拼多多全站商品SKU数据爬虫实战:Python自动化采集与清洗

在电商数据分析领域,SKU(Stock Keeping Unit,库存量单位)数据是洞察商品策略、价格体系和市场竞争格局的核心抓手。本文以拼多多平台为研究对象,系统讲解如何利用Python构建一套完整的全站商品SKU自动化采集与清洗流程。文章涵盖目标分析与反爬策略、网络请求模拟、数据解析、分布式存储、数据清洗与标准化,以及调度与运维等全链路环节,并提供可直接运行的代码示例。拼多多API返回的数据结构大致如下(已脱敏):json"goods_name": "某品牌运动鞋",

2201_76125261的博客 217

switch语句能否作用在byte上,能否作用在long上,能否作用在String上?——Java经典面试题系列

面试官:switch语句能否作用在byte上,能否作用在long上,能否作用在String上? 我:  &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。 &&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str

姚老板的黑店 2296

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

java基础面试题:switch语句能否作用在byte上,能否作用在long上,能否作用在String上?...

package com.swift; public class Switch_Test { public static void main(String[] args) { /* * switch语句能否作用在byte上,能否作用在long上,能否作用在String上? */ byte zijie ...

weixin_34128501的博客 125

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

java面试题:switch语句能否作用byte上,能否作用于long,能否作用于string上?

问题:switch的表达式是否可以为long?是否可以为string? 答: 在Java 5以前,switch(expr)中,expr只能是byte、short、char、int。从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始,expr还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

【程序员不弃】的博客 1295

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

JAVA面试题:SWITCH能否作用在BYTE、LONG、STRING上?

SWITCH能否作用在BYTE、LONG、STRING上? switch可作用于char byte short int switch可作用于char byte short int对应的包装类 switch不可作用于long double float boolean,包括他们的包装类 switch中可以是字符串类型,String(JDK1.7之后才可以作用...

qq_38709565的博客 553

switch语句

switch语句 switch语句格式: switch(表达式) { case 值1: 语句体1; break; (中断,结束的意思) case 值2: 语句体2; break; … default: (默认的意思) 语句体n+1; break; } 执行流程: 1)表达式中的值和case中的 值1进行比较,匹配成功,就执行语句1,遇见break,switch 结束了 2)依次case...

qq_41462659的博客 1万+

Java面试题:switch能否作用在byte、long、String上?

switch可作用于char byte short int switch可作用于char byte short int对应的包装类 switch不可作用于long double float boolean,包括他们的包装类 switch中可以是字符串类型,String(JDK1.7之后才可以作用在string上) switch中可以是枚举类型(JDK1....

LS1117的博客 5908

8.switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?

public class Test { public static void main(String[] args) { int a = 1; switch (a){ case 1: System.out.println(1); break; default: System.out.println("default");

面试题库 637

【Java基础面试题】 switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String上?

换句话就是byte 和 short 类型的取值范围都可以被 int 类型完全覆盖。byte 的取值范围是 -128 到 127,在转换为 int 类型时不会导致精度损失或溢出。类型的值在Java中是64位的,它的取值范围更大,不像。那样可以被编译器在常量表达式中使用。或其他类型上进行条件分支判断,可以考虑使用。(Java 7及以上版本)以及枚举类型上。(Java 7及以上版本)。、枚举(Java 5及以上版本)、语句在 Java 中可以作用在。(Java 7及以上版本)、(Java 7及以上版本)、

m0_59252838的博客 459

Java中的 Switch 是如何支持 String 的?为什么不支持 long?

面试题文档来啦,内容很多,485页!由于笔记的内容太多,没办法全部展示出来,下面只截取部分内容展示。

2401_84003941的博客 1124
上一篇: java提高篇-----详解java的四舍五入与保留位
下一篇: String SringBuffer StringBuilder区别
ole_triangle_java
博客等级 码龄10年 82粉丝 83原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值