关于String中的一个递归问题

问题描述

关于String中的一个递归问题

今天学习java String时,遇到书上讲的一个递归问题,先上代码
import java.util.*;
public class InfiniteRecursion {

public String toStirng() {
    return "InfiniteRecursion address: "+ this +"n";
}
public static void main(String[] args) {
    List<InfiniteRecursion> list = new ArrayList<InfiniteRecursion>();
    for(int i = 0; i <2; i++)
        list.add(new InfiniteRecursion());
    System.out.println(list);
}

}
书上讲到在toString()方法里面,编译器会将this转化为String,而转换时会调用toString()方法,这样就产生了递归调用。。我思考了也这么觉得,,但是运行代码时没有报错。把this换成super.toString()也能运行。求请教,为什么没有递归(书上讲的java SE5,我的编译器是1.7的)。

解决方案

不会递归。因为你重写的是InfiniteRecursion的toString,而你调用的是List<InfiniteRecursion>的toString

解决方案二:

这么写才会递归调用

package string;

public class InfiniteRecursion {

@Override
public String toString() {
    //this关键字会调用this.toString()方法,产生递归
    //修改为super.toString()
    return "InfiniteRecursion : " + this;
}

public static void main(String[] args) {
    InfiniteRecursion ir = new InfiniteRecursion();
    System.out.println(ir.toString());  //Exception in thread "main" java.lang.StackOverflowError

}

}

解决方案三:

不会调用toString

http://ideone.com/cffA6l
返回的是类名@引用地址

解决方案四:

import java.util.*;
class Ideone {
public String toStirng() {
    return "InfiniteRecursion address: "+ this +"n";
}
public static void main(String[] args) {
    List<Ideone> list = new ArrayList<Ideone>();
    for(int i = 0; i <2; i++)
        list.add(new Ideone());
    System.out.println(list);
}
}

在线编译运行结果
[Ideone@b8fba5, Ideone@9133f6]

解决方案五:

我的测试代码:

     public static void main(String[] args) {
        EverhThingTest ett = new EverhThingTest();
        ett.printList();
        // ett.printAbclr();
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "ssss"+this+"n";
    }
    private void printList() {
        // TODO Auto-generated method stub
        List<EverhThingTest> list = new ArrayList<EverhThingTest>();
        list.add(new EverhThingTest());
        list.add(new EverhThingTest());
        System.out.println(list);
    }

你这个问题确实很有意思,建议你在输出时打个断点跟一下,我根据你的代码测试了一下,我这里是可以递归调用,程序没有结果,会报Exception in thread "main" java.lang.StackOverflowError。从下面的错误信息可以看到递归调用了,如下:

     Exception in thread "main" java.lang.StackOverflowError
    at java.lang.System.arraycopy(Native Method)
    at java.lang.String.getChars(String.java:854)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:391)
    at java.lang.StringBuilder.append(StringBuilder.java:119)
    at java.lang.StringBuilder.<init>(StringBuilder.java:93)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    at java.lang.StringBuilder.append(StringBuilder.java:115)
    at EverhThingTest.toString(EverhThingTest.java:16)
    at java.lang.String.valueOf(String.java:2826)
    后面还有...

我在JDK1.6和1.7上都试过了,都是不可以的。不知道你的1.7为啥不能递归调用。

顺便说一下,输出list时,调用的toString方法在AbstractCollection类中(我两次跟代码都是跟到了这里,你自己看下是不是一致),代码如下:

     public String toString() {
        Iterator<E> it = iterator();
        if (! it.hasNext())
            return "[]";

        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e == this ? "(this Collection)" : e);
            if (! it.hasNext())
                return sb.append(']').toString();
            sb.append(',').append(' ');
        }
    }

上面的sb.append(e == this ? "(this Collection)" : e);语句中,会调用StingBuilder的append(Object obj)方法,代码如下:

     public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

而上面的String.valueOf(obj)方法的代码如下:

     public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

可以看到,最终还是指向了obj的toString方法,也就是你自己定义的toString方法。

建议你断点调试下,看看问题所在,期待你的回复。

解决方案六:

刚才那个确实没有调用InfiniteRecursion的toString()方法,但是现在这个是调用了RecursionTest的toString()方法。而且也发生了递归。
import java.util.ArrayList;
import java.util.List;
class RecursionTest {
public String toString() {
System.out.println("this is called");
return "recursion: "+this;
}
}
public class Test {

public static void main(String[] args) {

    List<RecursionTest> lr = new ArrayList<RecursionTest>();
    lr.add(new RecursionTest());
    System.out.println(lr);
}

}

解决方案七:

统一回复一下,我把toString()方法名写错了,并没有调用我的这个方法,所以最终还是会调用toString()的,也产生了递归了。

时间: 2024-09-26 19:16:24

关于String中的一个递归问题的相关文章

c++-每次读取一个字符存入一个string中,最少读取100个字符,应该如何提高程序的性能?

问题描述 每次读取一个字符存入一个string中,最少读取100个字符,应该如何提高程序的性能? <C++ Primer 第五版>习题9.42 假定你希望每次读取一个字符存入一个string中,而且知道最少需要读取100个字符,应该如何提高程序的性能? 解决方案 string s(100,' ');//事先构造一个100个字符的string对象 while(--) { --//填充s int size =s.size();//保存s的大小 if(s.size()>size)//每次填充检

求助:JavaScript中,怎么把一个string中的子串替换成其他的子串?

问题描述 我想写一个JavaScript函数,将传来的字符串,中的一个子串替换掉,该怎么写呢?? 解决方案 解决方案二:varnewstring=oldstring.replace("子串","替換的串"); 解决方案三:以下示例,将字串s中的asd换为空.<script>varre=/asd/g;vars='asdfgggasdfdfdf';alert(s.replace(re,''));</script> 解决方案四:replace()解

请大家帮我看看这个问题吧: 关于在后台代码中 定义一个string的问题?

问题描述 我在后台代码中是这么写的: publicpartialclass_Default:System.Web.UI.Page{privatestringfile_Path=ConfigurationManager.AppSettings["FileUploadPath"].ToString();privatestringfullFilePath=Server.MapPath(file_Path).ToString();}错误是: 错误1非静态字段.方法或属性"System

C#中如何搜索一个string中一共出现某个字符的次数?

问题描述 比如要判断一篇文章中出现"red"的次数如何实现? 解决方案 解决方案二:strings;strings1=s.replace("red","");return(s.length-s1.length)/3;解决方案三:用正则也可以~解决方案四:较简单方式//S1待判定字符串:red需要判定出现次数的字符串string[]S2=S1.Slip("red");//i为red出现的次数inti=S2.Count;解决方案五

根据前序和中序非递归创建二叉树

问题描述 根据前序和中序非递归创建二叉树 2C 怎样才能创建二叉树?传入参数T后,T不断被改变,我只想创建T的子树.然后以T为头节点.struct BTNode{ char data; BTNode lchild ; BTNode *rchild; //左右孩子指针} ;typedef BTNode *BT;/由先序和中序非递归创建二叉树*/void CreatBT2(BT &T string preStr string inStr){ stack stack; int index1index2

求一个递归修改文件夹内全部子文件和文件夹名的程序(batch或者perl)

问题描述 求一个递归修改文件夹内全部子文件和文件夹名的程序(batch或者perl) 需求是这样的: 递归修改文件夹中所有名字带"aaa"字符串的 文件夹名或者文件名改成 bbb 例如: 01_aaa |_01_aaa_01 |_nbdaaa_01.txt |_nbcaaa_02.txt |_02_aaa_01 改成 01_bbb |_01_bbb_01 |_nbdbbb_01.txt |_nbcbbb_02.txt |_02_bbb_01 解决方案 http://blog.163.c

怎样在Visual C# .NET中实现一个DataSet的不同记录的选取

visual 怎样在Visual C# .NET中实现一个DataSet的不同记录的选取来自:Microsoft Knowledge Base Article – 326176,地址: http://support.microsoft.com/default.aspx?scid=kb;EN-US;326176 摘要: 这是一篇基础性由浅入深的文章,这篇举例说明了怎样实现并怎样使用一个DataSetHelper类,该类使用简洁代码来创建一个新的使某个DataTable对象指定的某列的的值具有唯一性

ASP中FSO加递归生成文件列表(xml)

本来生成这个xml文档是为了开发一个ftp的搜索,后来由于没有资料参考怎么搜索xml文档,也就放弃了.其中最重要的是递归的算法.生成文件列表的速度很快.这个程序可以用于生成播放列表之类的东东.需要IIS的FSO组件支持.生成类似下面的XML文档 <?xml version="1.0" encoding="gb2312"?> <ftp ip="10.1.228.228"> <DIR path="Game&qu

php 5.6版本中编写一个PHP扩展的简单示例

 这篇文章主要介绍了php 5.6版本中编写一个PHP扩展的简单示例,本文给出扩展实现代码.编译方法.配置方法和使用例子等内容,需要的朋友可以参考下     有时候在php本身没有满足需求的api时候,需要自己写相应的扩展,扩展写完之后进行编译,即可加入自己的开发环境中,扩展php的功能. 这里实现一个连接字符串和int型数的连接操作的简单扩展. 首先,下载最新的php源码安装包,进入ext/目录,新建extstrcat.def: 代码如下: string extstrcat(string st