Java字符串参数

时间:2008-12-05 01:24:42

标签: java parameters string idioms

我来自.net背景,想知道创建一个方法的可接受方式,该方法返回一个布尔值并修改一个通过参数传入的字符串。我理解字符串在Java中是不可变的,因此下面的代码片段将始终产生一个空字符串。我被限制只返回布尔值。不能抛出例外情况。如果我需要将String类包装在一个StringHolder中,我可以在哪个包中找到它。

public static void DoStuff()
{
    String msg = "";
    if (GetMessage(msg))
    {
       System.out.println(msg);
    }
}

11 个答案:

答案 0 :(得分:9)

使用java.lang.StringBuilder - 基本上是一个可变的String。但是,返回修改后的String会更安全,更“Java样式”。

答案 1 :(得分:6)

我强烈建议您不要使用StringBuilder,持有者或类似的东西。他们是黑客。你想与Strings合作,而不是建设者。

最明显的方法是返回包含要返回的数据的对象。大卫的[bombe.livejournal.com]解决方案涵盖了这一点,所以我不再重复了。但是,我建议不要试图使它成为通用的数据球,使其具体化。使它像一个对象,也许它甚至可以成长为真正的行为。 (如果你真的想去城里,隐藏构造函数并改为给它一个静态的创建方法。)

第二种方法,在Java中不太受支持,是反转调用。而不是返回结果,告诉回调结果。

(更重要的)使用代码会是这样的(它看起来有点奇怪,因为它不是特定的,也不是通用的):

String userMessage = thing.doStuff(new StuffHandler<String>() {
    public String stuff(boolean success, String message) {
        return message+" was "+(success ? "succesful" : "unsuccesful");
    }
});

实现类似于:

public interface StuffHandler<T> {
    T stuff(boolean success, String message);
}

[...]

    public <T> T doStuff(StuffHandler<T> handler) {
        handler.stuff(isSuccess(), getMessage());
    }

第三种方法就是将方法分解为两种。这可能是也可能不可行。

答案 2 :(得分:5)

首先我可能不会有这些要求。我相信他们可以解决。如果您不想这样做,我建议您为两个结果返回一个容器对象:

public class ResultContainer {
    private final boolean success;
    private final String result;
    public ResultContainer(boolean success, String result) {
        this.success = success;
        this.result = result;
    }
    public boolean isSuccess() { return success; }
    public String getResult() { return result; }
}

在您的主要代码中:

ResultContainer resultContainer = GetMessage(message);
if (resultContainer.isSuccess()) {
    System.out.println(resultContainer.getResult());
}

GetMessage()显然会创建ResultContainer的新实例并将其返回,并填充返回值。

(使用Generics作为ResultContainer留给读者的练习。)

答案 3 :(得分:3)

通过使用泛型,可以将更优雅的持有者类重用于任何类型的对象:

public class Holder<T> {
  T item;
  public Holder( T item) { set( item);}
  public T get( ) { return item;}
  public void set( T item) { this.item = item;}
}
然后

DoStuff( )看起来像:

public static void DoStuff( ) {
  String msg = "";
  Holder<String> holder = new Holder<String>( msg);
  if ( getMessage( holder)) { System.out.println( holder.get( ));}
}

GetMessage( )必须致电holder.set( a_string)

答案 4 :(得分:2)

Java是一种基于类的面向对象语言,因此它的习惯用法倾向于创建类来封装数据及其周围的行为。

你有一个数据 - 消息 - 以某种方式获得,然后如果满足某些条件,则用其它方法完成。使该行为成为外部控制对象中的gets,ifs和其他操作的序列通常表明程序员不理解OOP。

  

我被限制只返回布尔值。不能抛出异常。

我建议你应该使用Fortran或C而不是Java吗?过程语言通常具有变异的惯用语并返回一个标志,这非常适合于该范例(在没有自动内存管理的情况下,调用者创建并传入一个填充的缓冲区;这允许缓冲区在安全时被释放调用者完成了它; Java不需要这样做,所以如果你看看Map.get()它会返回一个String,如果它失败则返回null - 不需要管理调用者的内存)。至少,不要试图在惯用的Java中找到可接受的方法 - 有了这些限制,它就不会,并且强迫它们在你身上的人做了一个糟糕的选择,这意味着你要么有黑客攻击,或者最终使用详细的代码试图制作一个非hacky解决方案。

答案 5 :(得分:1)

您不能将字符串用作输出参数。这样做的方法是使用StringBuilder类,或者为失败返回null。

Discussion Here

答案 6 :(得分:1)

字符串是不可变的,所以是的,您需要将String包装在StringHolder中。您可以像

一样编写自己的
  class StringHolder
  {
     String msg;
  }

  StringHolder sMsg = new StringHolder();
  sMsg.msg = "";
  if (GetMessage(sMsg))
  {
     System.out.println(sMsg.msg);
  }

答案 7 :(得分:1)

一个简单的StringHolder将是一个String [1]。


bool GetMessage(String[] output)
{
     if(output.length < 1)
          throw new Exception("Output must be a String[1]");
     output[0] = "You win!";
}

public static void DoStuff()
{
      String[] msg = new String[1];
      if(GetMessage(msg))
      {
          System.out.println(msg[0]);
      }
}
但是,

StringBuilder可能是规范的方法。

答案 8 :(得分:1)

这是一个奇怪的要求。

为什么不以正确的方式(或者至少是java方式)做到这一点?就像试图从函数中获得两个结果一样。像减法(2,2)返回0和“早安先生”。

不管怎样,你可以试试这两个选项。

第一。 StringBuilder 不是最好用的,因为你没有“构建”一个字符串。

public static void doStuff(){
    String msg = "";
    StringBuilder sb = new StringBuilder();
    if ( getMessage( sb ) ) {
        System.out.println( sb );
    }
}

public static boolean getMessage( StringBuilder sb ) {
    if ( "".equals( sb.toString() )) {
        sb.delete( 0, sb.length() );
        sb.append("It was empty");
        return true;
    } else {
        return false;
    }
}

第二个 StringHolder (任何持有者)也不是java风格,但做的工作。这将是我所知道的大多数java开发人员使用的那个。

public static void doStuff(){
    String msg = "";
    String [] holder = { msg };
    if ( getMessage( holder ) ){
        System.out.println( holder[0]  );
    }
}
public static boolean getMessage( String [] holder ) {
    if ( "".equals(  holder[0] )) {
        holder[0] = "It was empty";
        return true;
    } else {
        return false;
    }
}

第三。选项。不是你问的问题,而是我会做什么的。不幸的是违反了“返回布尔”条件。

public void doStuff() { 
    String msg = "";
    String result = getMessage( msg );
    if ( result != msg ) {
        System.out.println( result );
    }
}
public static String getMessage( String msg ) {
    if ( "".equals(msg){
        return "It was empty";
    }
    return msg
}

选择一个。

注意

虽然不是每个人都喜欢这个(Jon Skeet会说“不被普遍接受”),但请看一下我正在使用的java编码风格(在同一行中以小写和大括号开头的方法)。有时候尊重你编写的平台是很重要的。至少那是我用C#编写的代码(很少顺便说一下)

答案 9 :(得分:0)

public boolean doStuff(String msg) { boolean boolTest = false; msg += "Appending something to msg"; int msgLength = msg.length(); if ( msgLength > 80 ) { boolTest = true; return boolTest; } return boolTest; }

这是你想要的吗?我假设布尔测试类似于测试改变的消息是否太长以至于显示(大于80长度)或类似的东西,并且您不需要调用另一个方法来更改doStuff中的消息字符串()。

但是,

可能完全偏离基地。 : - )

答案 10 :(得分:0)

首先你要编写程序并从代码中创建它们:

Process p = Runtime.exec("java GetMessage.class " + String);

提示:Runtime.exec应该在任何地方使用。然后你可以制作很多节目。

然后你等着拿回这样的状态代码:

if (p.returnCode() = 1) 
  Out.printWord("1 made back"):
else 
  {
  Out.printWord("B Made back");
  }

这样你就可以像其他程序那样使用程序了。最好使代码可以重用。从我这里拿走它,我已经在这里多年了。这就是专业人士如何制作代码。