if、while、for等 有加{}与没{}问题

TKD03072010 2011-05-29 11:00:15
http://topic.csdn.net/u/20110529/07/a617db5b-7c59-4b87-bfe6-a92388cc9b48.html?7510
这是在看了这个帖子里面火龙果前辈,引发的猜想
自己动手做几个试验,果真出问题了:

猜想:
for循环在没有加{}是不能识别变量的
只有加{}才能识别变量!

求解!!!
...全文
702 63 打赏 收藏 转发到动态 举报
写回复
用AI写文章
63 条回复
切换为时间正序
请发表友善的回复…
发表回复
码界一棵葱 2012-11-26
  • 打赏
  • 举报
回复
引用 61 楼 qybao 的回复:
引用 57 楼 ticmy 的回复: 首先,本来就是一条语句,硬是将它分成两条语句,按照这个结论分析的过程还能成立吗 引用 56 楼 qybao 的回复: 引用 54 楼 ticmy 的回复: 具体为什么不能这样,我不得而知,但“int result = 10相当于两条语句,即int result; result = 10,所以。。。”这个结论绝对是行不通的 如 p……
向大神致敬
TKD03072010 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 ticmy 的回复:]
谜题55:特创论
某些时候,对于一个类来说,跟踪其创建出来的实例个数会非常用有,其典型实现是通过让它的构造器递增一个私有静态域来完成的。在下面的程序中,Creature类展示了这种技巧,而Creator类对其进行了操练,将打印出已经创建的Creature实例的数量。那么,这个程序会打印出什么呢?

public class Creator {
public static void……
[/Quote]
学习咯,多谢前辈的解答哈!!!
oO临时工Oo 2011-05-30
  • 打赏
  • 举报
回复


其实这个问题很简单,就像在JAVA中不能定义 int k = 0L 一样;
仅仅是个语法问题,除非你要研究1+1为什么等于2。
TKD03072010 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 ticmy 的回复:]

没有大括号表示肯定只有一条语句,Java语言规范不允许一个变量声明语句作为一条语句在for、while或do循环中重复执行

这个在《java解惑》一书中也有提到
[/Quote]
谢谢前辈的解释!
TKD03072010 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 ticmy 的回复:]

扯淡

引用 15 楼 qybao 的回复:

引用 14 楼 zhouyuqwert 的回复:
还有这种
if (true) // 报错
int result = 10;
这个应该也跟重定义无关吧

11L也说了,int result = 10相当于两条语句,即int result; result = 10,所以相当于
if (true) {int result;}
r……
[/Quote]
这个说错了吗?
f873788003 2011-05-30
  • 打赏
  • 举报
回复
阿宝 哥你忒给力了 膜拜
TKD03072010 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 qybao 的回复:]

引用 14 楼 zhouyuqwert 的回复:
还有这种
if (true) // 报错
int result = 10;
这个应该也跟重定义无关吧

11L也说了,int result = 10相当于两条语句,即int result; result = 10,所以相当于
if (true) {int result;}
result = 0; //导致这个地方找不到定义
[/Quote]
非常感谢 阿宝前辈 的解答 !!!!
qybao 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 zhouyuqwert 的回复:]
还有这种
if (true) // 报错
int result = 10;
这个应该也跟重定义无关吧
[/Quote]
11L也说了,int result = 10相当于两条语句,即int result; result = 10,所以相当于
if (true) {int result;}
result = 0; //导致这个地方找不到定义
javawjn 2011-05-30
  • 打赏
  • 举报
回复
使用{}
是因为里面有多行代码
不是用{}
默认只会执行第一行代码。
杜乐 2011-05-30
  • 打赏
  • 举报
回复

for(int i = 0;i<10;i++){
Integer k = new Integer(i);
}

实际上就是循环创建十个k对象,如果没有{}的话,会存在重复定义的操作
龙四 2011-05-30
  • 打赏
  • 举报
回复
扯淡

[Quote=引用 15 楼 qybao 的回复:]

引用 14 楼 zhouyuqwert 的回复:
还有这种
if (true) // 报错
int result = 10;
这个应该也跟重定义无关吧

11L也说了,int result = 10相当于两条语句,即int result; result = 10,所以相当于
if (true) {int result;}
result = 0; //导致这个地方找不到定义
[/Quote]
杜乐 2011-05-30
  • 打赏
  • 举报
回复
加{}表示可以管住{}里面的所有代码, 如没有,只能管住它最靠近的下一行代码,前提是最靠近的那行代码只有一个操作
如:

Integer k ;
for(int i = 0;i<10;i++)
k = new Integer(i);
,只有一个赋值操作。


for(int i = 0;i<10;i++)
Integer k = new Integer(i);
有了两个操作,一个是声明,一个事赋值。
楼主可以试一试。
龙四 2011-05-30
  • 打赏
  • 举报
回复

谜题55:特创论
某些时候,对于一个类来说,跟踪其创建出来的实例个数会非常用有,其典型实现是通过让它的构造器递增一个私有静态域来完成的。在下面的程序中,Creature类展示了这种技巧,而Creator类对其进行了操练,将打印出已经创建的Creature实例的数量。那么,这个程序会打印出什么呢?

public class Creator {
public static void main(String[] args) {
for (int i = 0; i < 100; i++)
Creature creature = new Creature();
System.out.println(Creature.numCreated());
}
}

class Creature {
private static long numCreated = 0;
public Creature() {
numCreated++;
}
public static long numCreated() {
return numCreated;
}
}

这是一个捉弄人的问题。该程序看起来似乎应该打印100,但是它没有打印任何东西,因为它根本就不能编译。如果你尝试着去编译它,你就会发现编译器的诊断信息基本没什么用处。下面就是javac打印的东西:

Creator.java:4: not a statement
Creature creature = new Creature();
^
Creator.java:4: ';' expected
Creature creature = new Creature();
^

一个本地变量声明看起来像是一条语句,但是从技术上说,它不是;它应该是一个本地变量声明语句(local variable declaration statement)[JLS 14.4]。Java语言规范不允许一个本地变量声明语句作为一条语句在for、while或do循环中重复执行[JLS 14.12-14]。一个本地变量声明作为一条语句只能直接出现在一个语句块中。(一个语句块是由一对花括号以及包含在这对花括展中的语句和声明构成的。)
有两种方式可以订正这个问题。最显而易见的方式是将这个声明至于一个语句块中:


for (int i = 0; i < 100; i++) {
Creature creature = new Creature();
}

然而,请注意,该程序没有使用本地变量creature。因此,将该声明用一个无任何修饰的构造器调用来替代将更具实际意义,这样可以强调对新创建对象的引用正在被丢弃:

for (int i = 0; i < 100; i++)
new Creature();

无论我们做出了上面的哪种修改,该程序都将打印出我们所期望的100。
请注意,用于跟踪Creature实例个数的变量(numCreated)是long类型而不是int类型的。我们很容易想象到,一个程序创建出的某个类的实例可能会多余int数值的最大值,但是它不会多于long数值的最大值。

int数值的最大值是231-1,即大约2.1×109,而long数值的最大值是263-1,即大约9.2×1018。当前,每秒钟创建108个对象是可能的,这意味着一个程序在long类型的对象计数器溢出之前,不得不运行大约三千年。即使是面对硬件速度的提升,long类型的对象计数器也应该足以应付可预见的未来。

还要注意的是,本谜题中的创建计数策略并不是线程安全的。如果多个线程可以并行地创建对象,那么递增计数器的代码和读取计数器的代码都应该被同步:


// Thread-safe creation counter
class Creature {
private static long numCreated;
public Creature() {
synchronized (Creature.class) {
numCreated++;
}
}
public static synchronized long numCreated() {
return numCreated;
}
}

或者,如果你使用的是5.0或更新的版本,你可以使用一个AtomicLong实例,它在面临并发时可以绕过对同步的需求。

// Thread-safe creation counter using AtomicLong;
import java.util.concurrent.atomic.AtomicLong;
class Creature {
private static AtomicLong numCreated = new AtomicLong();
public Creature() {
numCreated.incrementAndGet();
}
public static long numCreated() {
return numCreated.get();
}
}

请注意,把numCreated声明为瞬时的是不足以解决问题的,因为volatile修饰符可以保证其他线程将看到最近赋予该域的值,但是它不能进行原子性的递增操作。
总之,一个本地变量声明不能被用作for、while或do循环中的重复执行语句,它作为一条语句只能出现在一个语句块中。另外,在使用一个变量来对实例的创建进行计数时,要使用long类型而不是int类型的变量,以防止溢出。最后,如果你打算在多线程中创建实例,要么将对实例计数器的访问进行同步,要么使用一个AtomicLong类型的计数器。
龙四 2011-05-30
  • 打赏
  • 举报
回复
没有大括号表示肯定只有一条语句,Java语言规范不允许一个变量声明语句作为一条语句在for、while或do循环中重复执行

这个在《java解惑》一书中也有提到
皮特张 2011-05-30
  • 打赏
  • 举报
回复
7楼 阿宝 给力。
TKD03072010 2011-05-30
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 qybao 的回复:]

引用 20 楼 zs312979674 的回复:
貌似 这位 仁兄是正解、

引用 11 楼 super_fish 的回复:
Integer k = new Integer(i);其实是两句语句的合并:Integer k;和k = new Integer(i);所以jia{}和不加{}不一样。

但是 System.out.println("hi, everybody!");只是一条……
[/Quote]
交流也是个学习的过程,呵呵,谢谢哈!!!
zakk89 2011-05-30
  • 打赏
  • 举报
回复
学习学习
zh_666 2011-05-30
  • 打赏
  • 举报
回复
学习 顶楼上
aotian16 2011-05-30
  • 打赏
  • 举报
回复
学习来了
lxy15329 2011-05-30
  • 打赏
  • 举报
回复
加括号只是为了控制作用范围而已吧
加载更多回复(41)

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧