早上看了java类库中java.util.Arrays 类的toString方法的源代码。如下:(这是JDK1.6的源代码)
    public static String toString(long[] a) {
        
if (a == null)
            
return "null";
    
int iMax = a.length - 1;
    
if (iMax == -1)
            
return "[]";

        StringBuilder b 
= new StringBuilder();
        b.append(
'[');
        
for (int i = 0; ; i++) {
            b.append(a[i]);
        
if (i == iMax)
        
return b.append(']').toString();
            b.append(
"");
        }
    }

for循环有点奇怪,中间的那个表达式是空的。其实即使加上了条件,for (int i = 0; i<=iMax ; i++) 和源程序是一个效果的,纯粹是多余的,但是我就是多余地加上了这条,结果编译出错了!提示我没有返回语句!

我又重新编写了两个小程序来验证一下:
下面这个能通过编译:
class Test{
    
static String m(){
        
int a =10;
        
for (int i = 0; ; i++)
            
if(i==a)
                
return "10";
    }
    
public static void main (String[] args) {
        System.out.println (m());
    }
}
for循环的中间语句是空的。

下面这个就不能编译了:

class Test{
    
static String m(){
        
int a =10;
        
for (int i = 0; i<=a ; i++)
            
if(i==a)
                
return "10";
    }
    
public static void main (String[] args) {
        System.out.println (m());
    }
}

其实加上的语句并没有改变原来逻辑结构。这是为什么呢?

如果在for的外面加上一个return语句,随便返回什么字符串,又能通过编译了!!!这个字符串永远不能输出的!!!根本就是个摆设!!!

class Test{
    
static String m(){
        
int a =10;
        
for (int i = 0; i<=a ; i++)
            
if(i==a)
                
return "10";
        
return "never be touch!!!";
    }
    
public static void main (String[] args) {
        System.out.println (m());
    }
}


另外如果像下面这样在for的中间表达式加上一个恒等式,又能通过编译了!!!这是为什么呢?请高手指点!
class Test{
    
static String m(){
        
int a =10;
        
for (int i = 0true==true ; i++)
            
if(i==a)
                
return "10";
    }
    
public static void main (String[] args) {
        System.out.println (m());
    }
}


附:这是JDK1.5的源码,谢谢GrayWolf!
1.6的代码到底比1.5的改进在哪里呢?我觉得1.5版的实现比较清晰,可读性好一点。
#  public static String toString(long[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";
#
# StringBuilder buf 
= new StringBuilder();
# buf.append(
'[');
# buf.append(a[
0]);
#
for (int i = 1; i < a.length; i++) {
# buf.append(
"");
# buf.append(a[i]);
# }
#
# buf.append(
"]");
return buf.toString();
# }



Feedback

# re: 有关方法返回一个很奇怪的问题!  回复  更多评论   

2007-11-01 19:12 by GrayWolf
你的代码有问题:
http://www.javaresearch.org/source/index.html 这里有在线的源码,就不用一个一个打上去了。哈哈。文章写得还不错。哎,自愧不如,看来,下次学新技术,我也得写点东西出来了


public static String toString(Object[] a) {
if (a == null)
return "null";
if (a.length == 0)
return "[]";

StringBuilder buf = new StringBuilder();

for (int i = 0; i < a.length; i++) {
if (i == 0)
buf.append('[');
else
buf.append(", ");

buf.append(String.valueOf(a[i]));
}

buf.append("]");
return buf.toString();
}

# re: 有关方法返回一个很奇怪的问题!  回复  更多评论   

2007-11-01 19:18 by GrayWolf
for循环有点奇怪,中间的那个表达式是空的。其实即使加上了条件,for (int i = 0; i<=iMax ; i++) 和源程序是一个效果的,纯粹是多余的,但是我就是多余地加上了这条,结果编译出错了!提示我没有返回语句!
=======================================
这里,你加了 i<=iMax ,for循环做完后,i = iMax + 1,所以你的
if (i == iMax)
return b.append(']').toString();
这句永远都不会执行到,所以编译器就提醒你了。
========================================
你的源码是不是有问题,我看的在线的,for循环中间是有条件的。

# re: 有关方法返回一个很奇怪的问题!  回复  更多评论   

2007-11-01 19:35 by Raylong
@GrayWolf
我上面那段代码是JDK1.6的,你的那个在线代码网站提供的是1.5的。

# re: 有关方法返回一个很奇怪的问题!  回复  更多评论   

2007-11-01 21:53 by zhrb
@GrayWolf
不是这样的,因为你的return语句在for里面,如果for中间加入任何判断条件,除非这个判断条件绝对为真(如空语句、ture、3>2),否则就有可能没法执行到这个循环中的return语句,编译器显然不允许这种情况发生,所以当return语句只在循环体内出现,就不允许for循环中间的那个语句出现类似i<a这样的充满不确定性的判断。简单一句话,就是包含return的那个句子,至少要让编译器觉得,这个return是可以执行到的,以减少出错的可能。
不过即使这样,还是架不住人们可能出现的语义上的错误,看下面这段代码:
public static int max(int a, int b){
for(;;)
if (false) return a>b?a:b;
}
从语义上分析,return是无论如何也执行不到的,但是编译器看到for内的语句肯定可以执行,并且里面还有return语句,所以就想当然的认为没错。至于到底有没有错,自己回去想想、试试一下就知道了。呵呵

# re: 有关方法返回一个很奇怪的问题!  回复  更多评论   

2007-11-01 22:24 by Raylong
@zhrb
原来如此啊!看来是我过分高估编译器的智能了,编译器能在一定程度上减少程序出错的可能。有时在一些细节上看起来比较笨拙……
zhrb,谢谢非常详细的解答!!!

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-01 23:55 by zhrb
@Raylong
个人认为编译器这样设计肯定有他的道理
编译器就应该做他应该做的事请,涉及复杂的语义的东西还是交给程序员,自作聪明可能反而把事情搞得复杂起来.呵呵

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 07:27 by Raylong
static String m(){
int a =10;
for (int i = 0; i<=a ; i++)
if(i==a)
return "10";
return "never be touch!!!";
}

是啊,我主要是觉得类似于上面的小程序,非要在最后加一个永远到达不了的return语句才能通过编译,看起来很不爽 呵呵 虽然这个小程序很容易改写。

我宿舍有一个学C++的,他做个同样的试验,结果超级晕!比java存在的问题还难以解释,看来我们java的编译器还是比较聪明的,比较严格的(相对而言)

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 09:06 by zhrb
@Raylong
我是觉得奇怪,为什么要这样写
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
为什么不写成

for (int i = 0;i<iMax ; i++) {
b.append(a[i]);
if (i < iMax - 1 ) b.append(", ");
}
return b.append(']').toString();

我感觉这样更直观啊。呵呵
不知道是不是出于效率上的考虑呢?

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 10:24 by 翔南
我一般重写toString都是向楼上那么写的
for (int i = 0;i<iMax ; i++) {
b.append(a[i]);
if (i < iMax - 1 ) b.append(", ");
}
return b.append(']').toString();

以后可以借鉴java源代码的写法,不过那样写怎么就效率高了?

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 11:19 by 翔南
for (int i = 0; ; i++) {
b.append(a[i]);
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
只因为for里面的if只有一次为真,只执行一次if后的语句?

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 11:26 by Raylong
@zhrb
是很奇怪,1.5版本的源码也没错啊,新的版本也没体现出高超的地方吧。为什么要重写呢?

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 11:30 by Raylong
@翔南
有可能是!而且我觉得比较大小的效率没有比较相等的效率高!
从位模式来看,比较大小要看这个数的全部,而比较是否相等就不一样了,只要看到第一个bit不一样就认定这两个数不相等。
不知道这么解释对不对 呵呵
如果是对的,那么细节就体现出水平了。

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2007-11-02 20:49 by zhrb
@Raylong
事实上,如果用位模式来比较是否相等的话,只要对两个数进行异或就好了,最多一次就好了
比较大小的话,可能比较麻烦吧( 还要考虑符号位,最少一次吧 )
可能真的是这样.呵呵

# re: 有关方法返回一个很奇怪的问题 - 问题已解决  回复  更多评论   

2009-05-25 18:42 by 卡不过
方法

只有注册用户登录后才能发表评论。


网站导航: