简单问题的背后:关于if后不加括号的讨论

回溯算法与卡特兰数:解析括号生成问题 回溯算法是解决组合问题的经典方法,通过系统性地探索解空间来寻找所有可行解。其核心原理是通过递归调用尝试各种可能性,并在不满足条件时回退(回溯)。在编程领域,回溯算法广泛应用于排列组合、子集生成等问题。括号生成问题是一个典型应用场景,要求生成所有有效的括号组合,这对理解递归和算法设计至关重要。该问题与卡特兰数密切相关,卡特兰数描述了有效括号组合的数量增长规律。掌握这些概念不仅能解决面试中的算法题,还能深入理解编译器语法检查等实际工程问题。本文通过Java代码示例,详细展示了如何用回溯算法高效生成括号组合,并分 阅读详情
看上去一个很简单的问题,结果却不是想象中的那样。 良好的编码习惯是多么的重要啊。

原文地址:http://topic.youkuaiyun.com/u/20080825/18/34F53E23-ECBC-4A91-B8B5-8C7F2A07F50A.html

测试的代码如下:
  1. public class TestPrintStream1 {
  2.   public static void main(String[] args) {
  3.     Class c = TestPrintStream1.class;
  4.     try {
  5.       Object o = c.newInstance();
  6.       
  7.       if (o instanceof TestPrintStream1)
  8.         TestPrintStream1 tt = (TestPrintStream1) o;// 这里为什么会报错呢,说tt 和 TestPrintStream1不能不解析
  9.     } catch (InstantiationException e) {
  10.       e.printStackTrace();
  11.     } catch (IllegalAccessException e) {
  12.       // TODO Auto-generated catch block
  13.       e.printStackTrace();
  14.     }
  15.   }
  16. }

那一行为什么会报错呢?if语句后面不是允许不加大括号吗?

2楼 java2000.net

if ()
后面不使用花括号时,里面不能出现声明,因为那个涉及到作用域,而没有花括号又没有作用域了。
个人理解。
boolean ok = true;
if(ok)
  MyClass c = new MyClass();
这样也是不允许的。
改成
MyClass c = null;
if(ok)
  c = new MyClass();
这样是可以的
这个代码问题和 instanceof 没有任何关系


6楼 segazk

Java 把 Test tt = new Test(); 当两条语句看待了相当于 Test tt; tt = new Test();

Eclipse 中报的语法错误是:
Test cannot be resolved tt cannot be resolved

cmd 下 javac 没通过编译报的错误是:
 D:/Test.java:x: 不是语句
Test tt
= new Test();
 
^ D:/Test.java:x: 需要 ' ; '
Test tt
= new Test();
 
^ 2 错误


20楼 bao110908
Java Language Specification 明确指出局部变量声明的作用范围是在一个
块内,也可以理解为在“{  }”内。for 循环可以不使用“{ }”的,但仅限于
执行语句(其中并不包括变量声明语句)

我们看到的代码是这样的:
01  public class TestPrintStream1 {
02
03      public static void main(String[] args) {
04
05          Class c = TestPrintStream1.class;
06          try {
07              Object o = c.newInstance();
08              if (o instanceof TestPrintStream1)
09                  TestPrintStream1 tt = (TestPrintStream1) o;
10          } catch (InstantiationException e) {
11              e.printStackTrace();
12          } catch (IllegalAccessException e) {
13              e.printStackTrace();
14          }
15      }
16  }
由于变量作用域的关系,编译器所看到的代码是这样的,注意 09 行的缩进!
01  public class TestPrintStream1 {
02
03      public static void main(String[] args) {
04
05          Class c = TestPrintStream1.class;
06          try {
07              Object o = c.newInstance();
08              if (o instanceof TestPrintStream1)
09              TestPrintStream1 tt = (TestPrintStream1) o;
10          } catch (InstantiationException e) {
11              e.printStackTrace();
12          } catch (IllegalAccessException e) {
13              e.printStackTrace();
14          }
15      }
16  }

从 08 和 09 行编译器所理解的代码中来看,很明显 08 行的 if 语句并没有
结束,因此编译器会认为 if 后面少掉一个语句结束的分号。

笨笨地编译器猜想你的代码应该是这样的,注意 08 行后面的分号
08              if (o instanceof TestPrintStream1);
09              TestPrintStream1 tt = (TestPrintStream1) o;

实际上编译器的这种理解并不是我们想要的。

为了不出现我们所不知的东西来困扰,应该老老实实地在 for, if, while 等语句后面加
上 {  },哪怕块中的语句只有一行。


37楼:wargrey
各位,这里有没有熟悉C语言的朋友,相信大家都知道,在C语言里,变量的声明都是要出现在作用域的第一条非赋值语句前的。所以java也是c风格的语言, 它也可能有类似的很细节的规则,就是,java的变量声明必须是一条语句。而java的每个作用域里面的语句分割符是“;”,if (true) statemenet;只是一条语句,并且如12楼所说,javac提示缺少;,因为它认为声明是一条新语句,而这里却不是。另一个方面javac在解析 到单行if时会假设后面应该是个表达式之类或语句,而声明不是关键字,所以它报出无法解析。

  
  1. if (true)
  2.     new Object();
并不报错。

但是
  1. if (true)
  2.      int a;
  3. if (true)
  4.      int a=3;

也都报了类似的问题。


接触过vb的朋友也知道,vb有块if语句和行if语句,虽然java没有明确提到,但是if (true) statemenet;就是行if语句。行内的作用域与if所在作用域相同。因为作用域是由{}决定的。只是lz提到的问题很难碰到(如果严格参考 java规范的化),所有平时也没人会去考虑。当然我无法证明这个作用域究竟是什么!

这是我的理解。


70楼:ZjJ_Sir
try {
      Object o = c.newInstance();
     
      if (o instanceof TestPrintStream1)
      {
        TestPrintStream1 tt = (TestPrintStream1) o;
      }
}这样很明确,tt的作用域在if(){}的{}内({}是块作用域的标志)所以程序没有问题,而:
try {
      Object o = c.newInstance();
     
      if (o instanceof TestPrintStream1)
        TestPrintStream1 tt = (TestPrintStream1) o;
}编译器在编译这段代码时,当编译到TestPrintStream1 tt = (TestPrintStream1) o;时,会确定tt的作用域是在try{}的{}中。这明确几点,编译器在编译if语句时,并不对if语句表达式的对错作出判断,程序在执行时才对if语 句表达式的对错做判断。还有就是编译器编译代码是顺序编译的。(这都是编译原理中的知识,这里要用到这些知识来解决这个问题)当编译器编译 TestPrintStream1 tt = (TestPrintStream1) o;时,编译器不能确定是否会生成tt对象(因为if语句表达式的对错没有确定)并且编译器不能确定这句后是否会用到tt对象。这样就有可能出现:tt对 象没有生成(if表达式错),而在TestPrintStream1 tt = (TestPrintStream1) o;的后面又要用到tt对象,这样程序会出错,也可能出现其他其他三种情况。但这已经不重要了,因为有了这种情况,tt的定义已经出现了歧义,所以编译器 无法编译。这有很多解决方法。

在做些说明:像以上的代码形式,
{
int j = 0;

if (j == 0)

  int i = 1;
}
在C、 c++ 和C#中都是正确的,即使在Vs2005中这样的Java代码也是正确的,因为这种形式的代码在不同的编译方法中会有不同的解释(比如这样的形式 i 的作用域被默认为与if(){}形式中的一样。那么这样的形式就会正确)。从这可以看出,1、编写代码时,尽可能的与规范靠拢,2.熟悉自己用得编译器


总结:

为了我们的代码安全,养成良好的编码习惯,及时if后面只有一个语句,我们也要加上大括号,for循环也一样。










<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
体素坐标(voxel_coors)在mmdetection3d中的理解 阅读详情

相关推荐

一周涨十万星,GitHub 爆火的 REA 逆向工程到底是什么?

REA 这波热度里,我一直没太想明白的是它为什么火在 AI 圈而不是安全圈。同类的 MCP 工具早就在了,技术上也谈不上新,真正变的只有一件事:门槛。门槛一降,参与的人就从"会逆向的工程师"变成了"会打字的任何人"。这大概也是争议的根源。护城河这件事,多数报道的共识是它从"你看不到我的代码"挪到了"你拿不走我的服务能力和业务理解"。这话对不对,现在没人拿得出证据,只能等下一批真实案例。哪天有人拿 REA 把某个还在卖钱的闭源软件啃出可维护的工程,那个答案才算落地。

优快云zhizunbao的博客 1203

if语句中什么时候可以省略大括号?

有大括号的时候 大括号里面所有的 都归if管。只有条件为真的时候 才会执行。 没有大括号的时候 只有下面的 一句 归if管, 也就是说 当只有一句的时候 大括号可以省略 其它的 没区别 //注意观察此代码中的if语句 login() { this.$refs.loginFromRef.validate(async (valid) => { //登录前的一个预验证 // console.log(valid) if (!valid) retur

imkaifan的博客 6502

Dataset - DeepFashion 服装数据集

Dataset - DeepFashion 服装数据集 [Dataset - DeepFashion] [Project - DeepFashion] 1. 服装类别和属性预测集 [Category - Attribute 下载] [百度网盘] 289,222 张服装图片 clothes images; 50 个服装类别 clothing categories 1,000 ...

长风破浪会有时,直挂云帆济沧海 2万+

if条件语句的大括号是否添加问

if条件语句的大括号是否添加问题 要求: 求出0到999的任意实数的 个、十、百位的值 下面为错误示范 #include <stdio.h> int main() { printf("请输入一个需要求其个、十、百位数,且在0~999之间的实数\n"); float a; int b,c,d; scanf("%f",&a); if(a<0) printf("该数没有在要求范围内\n"); else if(a>999) printf("该数没有

DXZFLY的博客 6598

ROS阿克曼小车避坑指南:TEB Local Planner参数调优实战(附完整配置文件)

本文针对ROS阿克曼底盘机器人,提供了TEB Local Planner参数调优的实战指南。文章深入剖析了阿克曼模型与TEB的协同工作原理,重点讲解了`min_turning_radius`、`cmd_angle_instead_rotvel`等关键参数的设置与调试方法,并分享了性能优化、避障行为调整的实用技巧,旨在帮助开发者避开常见陷阱,实现小车在复杂环境中的稳定、高效导航。

ik6789012的博客 502

从零部署奥比中光Gemini335L:Python SDK编译与手眼标定环境实战

本文提供了一份从零部署奥比中光Gemini 335L深度相机的完整实战指南。详细介绍了驱动安装、Python SDK编译、CMake配置及虚拟环境搭建等关键步骤,并重点解析了如何通过编译生成Python模块,最终实现深度图与点云数据获取,为后续的机械臂手眼标定工作奠定坚实基础。

weixin_29031161的博客 399

Java编程中 if()后不加大括号的问题

if后可以不加大括号{},只能控制if后一行的代码,今天为了代码美观,试了一下,结果: 这么写会报错: if(dataMap.isEmpty()) String dataStr= (String)dataMap.get("data"); 这样不报错: String dataStr=""; if(dataMap.isEmpty()) dataStr= (String)dataMap.get("data"); 原因是 if后面不可以创建新对象,做了new 操作会被编译为 new + 赋值两行.

chaoyue12312的博客 1万+

CANdelaStudio实战:如何用19服务快速编辑DTC快照数据(附Excel模板)

本文详细介绍了在CANdelaStudio中利用19服务高效编辑DTC快照数据的进阶技巧。通过导出DTC池至Excel进行批量编辑,结合‘Copy from DTC Pool’功能实现配置复用,并分享了构建自定义Excel模板与字段映射的实用方法,帮助工程师将繁琐的手动配置转化为工程化的批量处理,大幅提升诊断数据库开发效率。

weixin_29230773的博客 193

PHP if后面不加花括号

$a=5; #1、 if($a > 5)echo 1; echo 0; //编译后是: if($a > 5){ echo 1; } echo 0; #2、 if($a > 5) echo 1; echo 0; //编译后是: if($a > 5){ echo 1; } echo 0; #3 if($a >= 5) $=1; else $...

PHP,Java--在世悟空的博客 2147

WorkBuddy 连接百度网盘:能查能上传,但别指望 AI 帮你下载

本文介绍了如何通过WorkBuddy连接百度网盘实现文件管理功能。首先需要在百度开放平台创建应用并获取AppKey等凭证,然后通过拼接授权URL获取Access Token并填入WorkBuddy。实际测试表明,该连接器支持查看目录结构、搜索文件及上传文档,但无法实现文件下载和创建分享链接,原因是百度网盘MCP Server未提供相关接口。使用前需明确功能限制,该方案适合需要远程查阅网盘内容但不涉及下载的场景。

u011186532的专栏 2042

解密Whisper模型与Speaker Diarization的结合

本文介绍了如何将Whisper语音识别模型与Speaker Diarization(说话人分割)技术相结合,实现多人对话场景下的语音转录和说话人识别。文章详细讲解了技术背景、环境配置和代码实现方法,通过Pyannote进行说话人分割,结合Whisper进行语音转文本,最终输出包含说话人信息的完整转录结果。该解决方案适用于会议记录、访谈分析等场景,显著提升了语音处理的应用价值。

2501_90323865的博客 153

if() { } 与 if() 后面不加大括号

if()后面不加大括号的情况 条件成立就执行距离条件最近的语句(即以分号分割最近的语句); 相反,如果不成立就执行除第一个语句以外的语句; warnningText10(){ let a=0,b=0,c=0; if(1>2) a=2,b=3,c=4; console.log(...

sunny_day的博客 5553

YOLOv8【第十章:多任务扩展深度篇·第1节】YOLOv8-Seg 实例分割:Mask原型生成与系数预测原理解析!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏。该专栏系统复现并梳理全网各类 YOLOv8 改进与实战案例(当前已覆盖分类 / 检测 / 分割 / 追踪 / 关键点 / OBB 检测等方向),坚持持续更新 + 深度解析,质量分长期稳定在 97 分以上,可视为当前市面上 覆盖较全、更新较快、实战导向极强 的 YOLO 改进系列内容之一。

**My Coding Family** 1815

简单问题的背后 关于if后不加括号的讨论

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看上去一个很简单的问题

jgfyyfd的博客 1270

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

括号匹配问题

给定一个字符串,其中的字符只包含三种括号:花括号{ }、中括号[ ]、圆括号( ),即它仅由 “( ) [ ] { }” 这六个字符组成。设计算法,判断该字符串是否有效,即字符串中括号是否匹配。括号匹配要求括号必须以正确的顺序配对,如 “{ [ ] ( ) }” 或 “[ ( { } [ ] ) ]” 等为正确的格式,而 “[ ( ] )” 或 “{ [ ( ) }” 或 “( { } ] )

吴小宝的博客 2万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java的if后面为什么需要加括号,而go却不需要呢?

一对小小的圆括号,承载了两代编程语言创始人截然不同的思考。James Gosling在兼容与改良之间妥协,为Java铺就了90年代企业级开发的普及之路;Rob Pike抛弃历史包袱,用底层编译器创新重构语法规则,为云原生时代打造了极简高效的Go。语法细节看似微不足道,实则是一门语言工程理念最直观的缩影:Java选择向历史与存量生态让步,Go选择向未来大规模分布式开发看齐。当我们日常敲下if (err!= null)或if err!= nil。

weixin_44058951的博客 637

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

if(a=1) b=1;c=2;else d=3;报错:error: ‘else’ without a previous ‘if’,背后的逻辑及根本原因。

if(a=1) b=1;c=2;else d=3;报错:error: ‘else’ without a previous ‘if’,背后的逻辑及根本原因。

jingjingsikao的博客 3356

牛客网-括号区间匹配问题

括号区间匹配

qq164425443的博客 2304

C语言if语句大括号使用全解析:从语法隐患到工程最佳实践

在编程基础中,控制结构是实现逻辑分支的核心,其中条件判断语句是构建程序逻辑的基石。其原理是通过对表达式求值决定执行路径,正确的语法使用直接影响程序的确定性和可靠性。从技术价值看,严谨的语法规范能显著提升代码的健壮性、可维护性,并避免隐蔽的逻辑错误。在应用场景上,无论是算法实现、系统开发还是嵌入式编程,清晰的控制流都至关重要。本文聚焦于C语言中if语句加大括号这一具体实践,深入剖析不加括号可能引发的**维护性灾难**和**宏展开意外**等典型问题,通过编译器视角和实战案例,阐述为何始终使用大括号是保障代码质量

weixin_33691700的博客 499

Java中为什么不能在if()小括号内声明变量?

看代码: 下面代码是错误的 int a = 1; int b = 2; if((var c = a + b) > 2){} 而下面一行代码是正确的 int a = 1; int b = 2; var c = 0; if((var c = a + b) > 2){} 两者之间区别在于局部变量c声明的位置,第一个c在if小括号内声明c这是不行的,因为局部变量这能在1、方法中;2、代码块...

java1592724884的博客 3210

LeetCode:22 括号生成

LeetCode:22 括号生成 题目描述 给出n代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。 例如,给出n = 3,生成结果为: [ ((())), (()()), (())(), ()(()), ()()() ] 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。 例如,给出&...

Sword1996的博客 218

括号配对问题

 描述 现在,有一行括号序列,请你检查这行括号是否配对。 输入第一行输入一个数N(0输出每组输入数据的输出占一行,如果该字符串中所含的括号是配对的,则输出Yes,如果不配对则输出No

GYGoyaya 730

小括号问题全解:从有效性校验到最长有效括号子串的算法与工程实践

括号匹配是编程面试和文本解析中非常基础的一类算法问题,核心通常围绕左右括号的配对与嵌套展开。理解这类问题的关键在于掌握计数器、栈、动态规划和双指针等经典数据结构与算法技巧。其中,计数器可用于判断括号字符串是否有效,栈通过存储下标可精准计算最长有效连续片段,而双指针则能实现常数空间复杂度的优化。这些思路不仅服务于算法竞赛,在编译器语法解析、代码格式化、表达式校验等真实工程场景中同样具有实用价值。本文从括号问题的三个典型问法入手,系统梳理不同解法背后的原理与边界条件,帮助读者建立从基础校验到最优子段搜索的完整认

weixin_32612263的博客 245
上一篇: Java侦听系统终止事件,做好扫尾工作
下一篇: 代码共享功能上线了,欢迎大家提交自己原创,收集,完善,增强的好代码与大家共享
老紫竹
博客等级 码龄19年 1万+粉丝 1252原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值