本帖最后由 bgsbati1987 于 2010-05-09 10:41:51 编辑

解决方案 »

  1.   

    代码格式上不是太好,可能是从IDE直接拷过来的原因,大家包涵一下,呵呵。
      

  2.   

    1,应先查找匹配的,如果没找到,则按default处理,所以放在最后
    2,应该加上break,这样如果找到匹配的,执行流程会跳转至switch主题的末尾应该知道原因了吧!
      

  3.   

    对于第二个问题,因为执行return时,会跳出并返回值给next方法,所以不会有多个对象返回
    第一个问题我想可能是因为你要求返回一个对象,但case代表的是可能执行,但并不一定执行,如果case都不执行就会出错,default则默认返回一个null,
      

  4.   

    default要放最后的,
    你这里使用了return,后面再写break当然是走不到的source,当然会给你提示。都已经return了,后面的东西还怎么走。
      

  5.   

    switch的写法不太对,switch对每个子语句都要break
    如:
    int i=2;
    switch(i){
    case 1:System.out.println("这是1"); break;
    case 2:System.out.println("这是2");break;
    default:System.out.println("这是default"); break;
    }
    这样写试试,default一个要写在结尾。
      

  6.   

    补充一下:
    不要在switch的子语句中写 return 如果这样的话,代码不会执行swticth块以后的代码。
    如果 这是个函数要个返回值,要的是case中的结果.就 return 然后再加个break;
      

  7.   

    default要写在结尾的
    你让它返回return new Circle();
    所以后面的break就不执行了
      

  8.   

    第二个问题明白了,应该是return的原因。第一个问题还是不太明白,为什么default要放到最前面,放到前面是书上的写法,而且这种写法能运行出正确结果。放在最后反而不行。
      

  9.   

             class RandomShapeGenerator {
                 private Random rand = new Random(47);
                 Shape next() {        //三个case中的Circle、Square、Triangle分别是Shape的派生类
                             switch(rand.nextInt(3)) {
                             case 0: return new Circle();
                             case 1: return new Square();
                             case 2: return new Triangle();
                             default: throw new InternalError("Mission Impossible"); // 不可能发生
                         }
                  }
              }
      

  10.   

    你default在最后,代表有一个分支(虽然不可能运行到,但是编译器没法判断)没有return或者/throw。
      

  11.   

    不建议你“养成default放最前面”的习惯
      

  12.   

    可能是我没有表达清楚,问题1里的default放在前面是书上的的写法,而且运行结果是正确的,放在最后就会出现问题。问题2中的break我觉得楼下的朋友说的还是有道理的,用return已经跳出了。
      

  13.   


             class RandomShapeGenerator {
                 private Random rand = new Random(47);
                 Shape next() {        
                             Shape s;
                             switch(rand.nextInt(3)) {
                             default:
                             case 0: s = new Circle();break;
                             case 1: s = new Square();break;
                             case 2: s = new Triangle();break;
                             default: break;
                         }
                         return s;
                  }
              }
    这样试试。。
      

  14.   

    为什么要用两个default呢?第一个有什么作用?
      

  15.   

    default 放在最后,
    每条语句都要加break,如有特殊要求可以不加,
    如果default之前的条件都不匹配就进入default,
    不加break会导致switch穿透,SCJP里面有很多相关的题目。
      

  16.   

    如果放在前面是不是说“case 0: return new Circle();”是default的一部分?这样解释似乎可以行得通昂。如果根本不加,IDE会提示“This method must return a result of type Shape”,难道rand.nextInt(3)还会有不生成0-2的情况吗?
      

  17.   

    break的问题大概明白了。这个default的用法是书上的,而且能出结果,可能是“case 0: return new Circle();”是default的一部分,这样做是为了防止case语句都不执行的情况,不过这种情况可能发生吗?
      

  18.   

       我想这个是必须的吧,首先要是你的值是0,1,2无所谓,但要是大于2那么就是问题了,要是你的default在最后面那么假如大于2,那么就没有返回值了,就会报错,系统肯定察觉到了,而放在最前面,因为没有break;所以还会继续往后执行!!所以不必有return。
    第二:对于return,其实和break在一些方面功能是一样的。
      

  19.   

    break问题明白了,return已经跳出了。default放在最后出问题的,应该是这个default也需要处理一下,返回一个Shape或他的派生类。
      

  20.   

    恩,明白了,default这个问题是我没理解随机数方法内参数造成的, “private Random rand = new Random(47);”这句里的47这个种子是伪随机数生成器的内部状态的初始值,生成一个伪随机序列,而“rand.nextInt(3)”则是选取这个伪随机序列中可能出现0-2,这三个数。所以有可能出现不是0-2,即不能用三个case解决的情况。
      

  21.   

     “default: throw new InternalError("Mission Impossible"); ”这句不能发生吗?如果rand.nextInt(3)得值大于2呢?“private Random rand = new Random(47);”这句中的生存的伪随机序列中应该有不包括0-2的情况吧。
      

  22.   

    SCJP,这个认证以前没注意,井底之蛙了,呵呵
      

  23.   

    不会大于2的,rand.nextInt(3),取值范围是大于等于0,小于3,所以不会出现大于2的整数。
      

  24.   

    不晓得你看的哪个版本的哪一章的tij,我没发觉这样的source
      

  25.   


    编译器不会理解nextInt() between 0-2,所以,必须让所有分支都有return/throw我的做法类似:
      

  26.   

    defaut 应该放在最后去匹配
    至于为什么不用 break 是因为你有 return 
    本例中 return 包含了 break 的效果
      

  27.   

    那么这个rand.nextInt(3)有什么用呢?
      

  28.   

    我刚看了第四版英文版,搜索了一下,没有你这段source,估计是翻译者做的事情。
      

  29.   

    恩,break的问题大致明白了,不过还有个问题要请教,“rand.nextInt(3)”这句能不能产生大于2的数?如果不能的话,default放在前面又有什么用呢(default放在前面的确可以正常运行)?
      

  30.   

    1.default放最前面是为了实现0,1,2以外的时候默认为0生成一个Circle对象
    2.switch分支中已经return跳出方法,当然不需要在加break
      

  31.   

    switch 的语法要求有个default吧
    rand.nextInt(3)不可能产生大于2的数如果你把 default 放在最后 你要加个 return null 什么的
    switch 里如果没有某个分支如果没有break当匹配到该值的时候就会把后边的语句都执行一遍 
      

  32.   

    不会产生大于2的,这段程序,default没什么意义
      

  33.   

    我相信,如果你多跑几次这段程序,看看,3和4的情况,就明白default的作用了int x = rand.nextInt(5)
    switch(x) {
      default:
      case 0: 
      System.out.println(x);
      return new Circle();
    case 1: 
      System.out.println(x);
      return new Square();
    case 2: 
      System.out.println(x);
      return new Triangle();
    }
      

  34.   

    这题很简单啊!
     switch(rand.nextInt(3)) {
                             default:
                             case 0: return new Circle();
                             case 1: return new Square();
                             case 2: return new Triangle();
                         }rand.nextInt(3)  是在运行期产生的,switch的值可以是个变量,但case里面的值一定要常量,这个时候编译器并不知道rand.nextInt(3)的值是多少,这个都是编译期就要断定的!
    至于default放在前面不出错 ,放在后面就出错,是因为 该例子中放前面会往下执行,程序执行过程是从上到下的,因为例子中没有break;  所以不管rand.nextInt(3)值是多少都会执行到return new Triangle();   保证有返回值。 而你把default放在最后,如果程序从上到下执行到return new Triangle();
    的话,因为没有break;所以还会执行default  ,而default里面什么也没有,没有返回值,所以也会报错, 修改一下也给  default:后面加个默认的实例就可以了去看看java的字节码    可以使用   javap -c 类名       查看,很好用的工具
      

  35.   

    1.default这样写是利用了switch不加break会导致穿透的特点。这样写的效果就是default与case 0都执行return new Circle();//如判断每月的天数可以这样写
    switch(month)
    {
      default:
      case 1:
      case 3:
      case 5:
      case 7:
      case 8:
      case 10:
      case 12: return 31;    //day = 31;break;
      case 4:
      case 6:
      case 9:
      case 11: return 30;
      case 2: if(闰年) return 29;
              else  return 28;
           }2.因为return后方法就结束了,所以每个分支进去后return一个对象,后面的代码就不再走,不会产生多个对象
      

  36.   

    41楼的朋友说“rand.nextInt(3) 是在运行期产生的,switch的值可以是个变量,但case里面的值一定要常量,这个时候编译器并不知道rand.nextInt(3)的值是多少,这个都是编译期就要断定的!”,我在网上找了一圈,也没找到“rand.nextInt(3)”究竟是什么时候运行。如果“rand.nextInt(3)”真的在编译阶段没有确定值,那么这个程序里的default的作用似乎也可以这样理解吧,他是为了“应付”编译的阶段,因为编译时不知道rand.nextInt(3)它的取值在0-2中间,所以就有可能出现无法用三个case处理的情况,因此要用一个default(这里的case 0也同时是default)处理一下。
      

  37.   

    觉得你对于“rand.nextInt(3) 是在运行期产生的,switch的值可以是个变量,但case里面的值一定要常量,这个时候编译器并不知道rand.nextInt(3)的值是多少,这个都是编译期就要断定的!”应该是行得通的。不过关于break的问题,我觉得还是大家说得有道理,return本身就已经返回了,就不用break了。
      

  38.   


    是的,没有太关注题目,没有注意到return   
      

  39.   

    感觉你写的程序有点搞人。      应该要加break  而且,不应该是return  你前面没定义返回值啊,用System.out.println();试试
    然后把程序调整下应该OK。
      

  40.   

    这个不是我写的,书上的。return是因为next()方法前面已经有了Shape,它返回的是一个Shape类型的对象。
      

  41.   

    每个分支要加个BREAK哈,DEFAULT放最后~
      

  42.   

    不用加break也行,因为return已经返回了。
      

  43.   

    恩就是这样  在case里面值没有匹配的情况下   就执行default里面的case 0:  也就是case 0 是包含在default里面的
      

  44.   

    结贴之前总结一下在这个问题中学到的一些知识,希望对以后看到这个帖子的朋友有些帮助,不过都是自己的看法,有不对之处还希望大家赐教。1、“private Random rand = new Random(47);”这条语句生成了一个伪随机序列(并非真正的随机,而是按一定的算法生成的。其中47作为种子,这样每次运行程序的到的伪随机序列都是相同的。如果用Random(),我没记错的话,种子取的是系统时间,所以每次运行伪随机序列都不一样)。rand.nextInt(3),取自此随机数生成器序列的并且在0-2之间整数。2、case语句后面不加break的原因是,语句中的return已经跳出了switch,不会在继续往下执行了。3、default放在最前面,我猜想原因可能有二(这些结论完全是自己的猜想):一是rand.nextInt(3)是在运行时确定值的,IDE在编译的时候并不知道,所以IDE会找default语句,而default放在前面,把case 0作为了default,防止了IDE的报错;二是由于用47作为种子生产的伪随机序列不一定含有0-2的这三个数,为了防止三个数都不存在的情况(这时要用到default),用case 0作为default来接收switch传了的信息。