Topic: switch语句用法的困惑 |
Print this page |
1.switch语句用法的困惑 | Copy to clipboard |
Posted by: othello Posted on: 2003-06-04 23:44 我在运行tij中的范例程序时,发现一个让我不解的事情。程序如下。 ------------------------------------------------- //: c07:Shapes.java // From 'Thinking in Java, 2nd ed.' by Bruce Eckel // www.BruceEckel.com. See copyright notice in CopyRight.txt. // Polymorphism in Java. class Shape { void draw() {} void erase() {} } class Circle extends Shape { void draw() { System.out.println("Circle.draw()"); } void erase() { System.out.println("Circle.erase()"); } } class Square extends Shape { void draw() { System.out.println("Square.draw()"); } void erase() { System.out.println("Square.erase()"); } } class Triangle extends Shape { void draw() { System.out.println("Triangle.draw()"); } void erase() { System.out.println("Triangle.erase()"); } } public class Shapes { public static Shape randShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } public static void main(String[] args) { Shape[] s = new Shape[9]; // Fill up the array with shapes: for(int i = 0; i < s.length; i++) s[i] = randShape(); // Make polymorphic method calls: for(int i = 0; i < s.length; i++) s[i].draw(); } } ///:~ ------------------------------------------------- 在程序中的randShape()中 public static Shape randShape() { switch((int)(Math.random() * 3)) { //default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } 有一个default:语句,我认为好象没什么作用呀,就去掉了,可是编译竟不能通过,提示missing return statement 下面不是有return语句吗? 我把default移到 case 2: return new Triangle(); 后面也是如此。 加上default而且必须放上最上面,就可编译通过,这是怎么回事呀?是不是运用switch语句的一个技巧? |
2.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: kavenlin Posted on: 2003-06-04 23:55 You can write public static Shape randShape() { Shape shape=null; switch((int)(Math.random() * 3)) { //default: case 0: shape=new Circle(); break; case 1: shape=new Square(); break; case 2: shape=new Triangle(); break; } return shape; } |
3.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: bean_wj Posted on: 2003-06-05 09:43 1.如果去掉default,则非0、1、2时没return。 2.default移到case2后,同样当非0、1、2时没return。 此函数必须要reuturn语句。 3.加上default在最上,则任何情况都有return。 |
4.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: othello Posted on: 2003-06-05 09:48 可是原来的程序在default后面也没有return语句呀,可是编译是可以通过的, 只不过default必须放在最前面,放在后面则不行,我主要想知道放在前面和 放在后面为什么会有不同的结果? 另外(int)(Math.random() * 3)的值只会有三种可能,即:0,1,2.这样应该不会 有其它的情况出现,那我们还需要default语句吗? |
5.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: 牛老板 Posted on: 2003-06-05 10:23 1. default在语法中是可选的. 2. 由于(fall-through)的存在,所以case的顺序是很关键的. 呵呵.... |
6.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: bean_wj Posted on: 2003-06-05 10:30 1.放在最后面一定错,因为没有return对应,放在前面如果值是非0、1、2则对应default,又因为没break,顺序往下return0。 2.编译器不会判断逻辑,和(int)(Math.random() * 3)的值有哪些情况没关系。 |
7.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: emarket Posted on: 2003-06-05 10:39 (switch.txt是排过版的) 一,首先理解3种情况 1.这种情况可以可以编译 int doSomething(){ if(true){ return 1; }else{ return 0; } } 2.这种情况就不可以 int doSomething(){ if(true){ return 1; } } 3.这种情况也不行 int doSomething2(){ if(true){ return 1; } if(false){ return 2; } } 明白了以上3种情况,你应该了解到,java compiler是怎么工作的了吧 他认为 if()else 才是可以完全覆盖的 但是 if(true) if(false) 则不是。 二,理解switch得default:如果没有其他条件满足,则执行default. 三,理解break在swith中的行为(这点不用我讲了吧),强调一点,case语句only提供入口 出口要break来把握,也就是说如果一个case block没有一个break,那么这个case会继续执行 (除非遇到return 或抛出异常)。 四,来看看你的问题 1. (没有default得情况) public static Shape randShape() { switch((int)(Math.random() * 3)) { //default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } 这样子理解你的程序: public static Shape randShape() { int i=((int)(Math.random() * 3)) ; if(i==0) return new Circle(); else if(i==1) return new Square(); else if (i==2) return new Triangle(); // else{ //default miss return //不能编译 } 2. default在末尾的情况 public static Shape randShape() { switch((int)(Math.random() * 3)) { case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); default: } } 这样子理解你的程序: public static Shape randShape() { int i=((int)(Math.random() * 3)) ; if(i==0) return new Circle(); else if(i==1) return new Square(); else if (i==2) return new Triangle(); else{ //default //donothing here, so miss return //不能编译 } 3. default在头的情况 public static Shape randShape() { switch((int)(Math.random() * 3)) { default:// no break here, if has a break, then can not compile case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } 这样子理解你的程序: public static Shape randShape() { switch((int)(Math.random() * 3)) { default: /*case 0*/ return new Circle(); // 因为没有break,这条default得的对等结果就是执行case 0; case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } so public static Shape randShape() { int i=((int)(Math.random() * 3)) ; if(i==0) return new Circle(); else if(i==1) return new Square(); else if (i==2) return new Triangle(); else{ //default return new Circle(); //has a return 可以编译 } 是不是有点糊涂了//hehe 其实简单来说, 1, 如果default在头,加上break照样不能编译(因为这样这条default得的对等结果就不是执行case 0了) 2, 如果default在尾,加上return new Circle()照样可以编译 3,其实把default(without break) 放在 case 2之前,都可以编译 switch.txt (3.23k) |
8.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: othello Posted on: 2003-06-05 14:52 这个问题我在csdn和cjsdn分别提问,大家可以参照这两个帖子。 csdn:http://expert.csdn.net/Expert/topic/1877/1877411.xml?temp=.4656793 cjsdn:http://www.cjsdn.com/post/view?bid=1&id=31157&sty=1 非常感谢大家这么耐心而又细致的解答,谢谢! 综合大家的观点和我自已的理解,做一总结如下: 1.为什么需要 default 语句? 在randShape()中,其实 (int)(Math.random() * 3 的结果只有三种可能,就是:0,1,2 好象default语句是多余的,实际上(int)(Math.random() * 3 的值只有在运行期才会得出, 而编译器事先无法知道只可能有三种结果,它认为还有其它的结果,并且 randShape() 要求 必须返回一个 Shape object ,因此编译器需要一个default语句。 其实在运行期,永远都不会执行 default 后面的子句,因为不可能出现三种结果以外的 情况,加入default 语句只是为了让编译器顺利通过编译。 这也是最初让我困惑的地方,在我的头脑中已经有了(int)(Math.random() * 3 只有三种 结果的想法,而这一切编译器不知道,我的思维方式与编译器的运作方式出现了错位。 emarket 老兄的示例很好,让我对这一问题有了了解。详见 emarket 的帖子。 2.为什么 default 语句(在其后没有子句的情况下)不能放在switch语句块的块尾。 public static Shape randShape() { switch((int)(Math.random() * 3)) { default: case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } 等价于 public static Shape randShape() { switch((int)(Math.random() * 3)) { default: return new Circle(); case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); } } 上面是default放在块头的情形。default 放在其它地方也可以,只是不能放在块尾 (在default后没有子句的情况下),当执行到default语句时,由于其后并无break, return语句,它会执行紧接于其后的语句(尽管在运行期default语句不会被执行)。 public static Shape randShape() { switch((int)(Math.random() * 3)) { case 0: return new Circle(); case 1: return new Square(); case 2: return new Triangle(); default: } } 编译器认为在三种结果之外情况下, randShape() 不能获得返回值。所以它不允许 编译通过。 有好几位朋友都提到这一点。 到此这个问题有了最终的解答,如果没有人对我以上的总结提出异议或补充的话,明天就 可以结帖了。再次感谢大家让我这么快就获得了答案。 |
9.Re:switch语句用法的困惑 [Re: othello] | Copy to clipboard |
Posted by: Hodex Posted on: 2003-06-10 14:06 呵呵 |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |